pageflow 17.1.0 → 17.2.0

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 (302) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +319 -345
  3. data/README.md +3 -4
  4. data/admins/pageflow/accounts.rb +6 -6
  5. data/admins/pageflow/entry.rb +10 -8
  6. data/admins/pageflow/membership.rb +11 -11
  7. data/admins/pageflow/translations.rb +5 -5
  8. data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
  9. data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
  10. data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
  11. data/app/assets/javascripts/pageflow/ui.js +0 -1
  12. data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
  13. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
  14. data/app/assets/stylesheets/pageflow/admin.scss +1 -0
  15. data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
  16. data/app/assets/stylesheets/pageflow/animations.scss +1 -0
  17. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +21 -5
  18. data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
  19. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
  20. data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
  21. data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
  22. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +0 -1
  23. data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
  24. data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
  25. data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
  26. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
  27. data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
  28. data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
  29. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
  30. data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
  31. data/app/assets/stylesheets/pageflow/editor/files.scss +230 -50
  32. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
  33. data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
  34. data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
  35. data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
  36. data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
  37. data/app/assets/stylesheets/pageflow/editor/list.scss +88 -38
  38. data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
  39. data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
  40. data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
  41. data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
  42. data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
  43. data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
  44. data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
  45. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
  46. data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
  47. data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
  48. data/app/assets/stylesheets/pageflow/ui/properties.scss +29 -0
  49. data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
  50. data/app/assets/stylesheets/pageflow/ui.scss +4 -2
  51. data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
  52. data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
  53. data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
  54. data/app/controllers/pageflow/editor/files_controller.rb +15 -6
  55. data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
  56. data/app/controllers/pageflow/entries_controller.rb +17 -13
  57. data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
  58. data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
  59. data/app/controllers/pageflow/review/comments_controller.rb +53 -0
  60. data/app/controllers/pageflow/revisions_controller.rb +4 -1
  61. data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
  62. data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
  63. data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
  64. data/app/helpers/pageflow/editor/config_helper.rb +3 -1
  65. data/app/helpers/pageflow/entries_helper.rb +24 -42
  66. data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
  67. data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
  68. data/app/helpers/pageflow/structured_data_helper.rb +4 -1
  69. data/app/helpers/pageflow/themes_helper.rb +1 -3
  70. data/app/helpers/pageflow/widgets_helper.rb +2 -1
  71. data/app/inputs/pageflow_permalink_input.rb +6 -2
  72. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
  73. data/app/models/concerns/pageflow/reusable_file.rb +1 -1
  74. data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
  75. data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
  76. data/app/models/concerns/pageflow/uploadable_file.rb +1 -1
  77. data/app/models/pageflow/comment.rb +30 -0
  78. data/app/models/pageflow/comment_thread.rb +65 -0
  79. data/app/models/pageflow/comment_thread_read.rb +22 -0
  80. data/app/models/pageflow/customized_theme.rb +3 -2
  81. data/app/models/pageflow/draft_entry.rb +20 -8
  82. data/app/models/pageflow/entry.rb +2 -0
  83. data/app/models/pageflow/entry_at_revision.rb +9 -1
  84. data/app/models/pageflow/entry_comment_summary.rb +114 -0
  85. data/app/models/pageflow/file_folder.rb +74 -0
  86. data/app/models/pageflow/file_reuse.rb +3 -2
  87. data/app/models/pageflow/file_usage.rb +8 -0
  88. data/app/models/pageflow/image_file.rb +24 -20
  89. data/app/models/pageflow/image_file_url_templates.rb +3 -3
  90. data/app/models/pageflow/legal_info.rb +38 -0
  91. data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
  92. data/app/models/pageflow/permalink.rb +1 -0
  93. data/app/models/pageflow/revision.rb +6 -2
  94. data/app/models/pageflow/site.rb +10 -0
  95. data/app/models/pageflow/used_file.rb +8 -2
  96. data/app/models/pageflow/widget.rb +2 -2
  97. data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
  98. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
  99. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
  100. data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
  101. data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
  102. data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
  103. data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
  104. data/app/views/pageflow/editor/files/_file.json.jbuilder +2 -1
  105. data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
  106. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
  107. data/app/views/pageflow/files/_file.json.jbuilder +2 -0
  108. data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
  109. data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
  110. data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
  111. data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
  112. data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
  113. data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
  114. data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
  115. data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
  116. data/config/locales/de.yml +152 -14
  117. data/config/locales/en.yml +150 -14
  118. data/config/routes.rb +14 -0
  119. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  120. data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
  121. data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
  122. data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
  123. data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
  124. data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
  125. data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
  126. data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
  127. data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
  128. data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
  129. data/db/migrate/20260728000000_create_file_folders.rb +17 -0
  130. data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
  131. data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
  132. data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
  133. data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
  134. data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
  135. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +8665 -3890
  136. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
  137. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
  138. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
  139. data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
  140. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
  141. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
  142. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
  143. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
  144. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +7 -5
  145. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
  146. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
  147. data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
  148. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
  149. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
  150. data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
  151. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
  152. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -7
  153. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
  154. data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
  155. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -0
  156. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
  157. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
  158. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
  159. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
  160. data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
  161. data/entry_types/scrolled/config/locales/de.yml +512 -65
  162. data/entry_types/scrolled/config/locales/en.yml +518 -52
  163. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
  164. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
  165. data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
  166. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
  167. data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
  168. data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
  169. data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
  170. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +205 -22
  171. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
  172. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
  173. data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
  174. data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
  175. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
  176. data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
  177. data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
  178. data/entry_types/scrolled/package/config/webpack.js +72 -0
  179. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
  180. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
  181. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
  182. data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
  183. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
  184. data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
  185. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
  186. data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
  187. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +71 -21
  188. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
  189. data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
  190. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
  191. data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
  192. data/entry_types/scrolled/package/contentElements-editor.js +1915 -1097
  193. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  194. data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
  195. data/entry_types/scrolled/package/editor.css +1 -0
  196. data/entry_types/scrolled/package/editor.js +8667 -4077
  197. data/entry_types/scrolled/package/entryState.js +1600 -0
  198. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
  199. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
  200. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
  201. data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
  202. data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
  203. data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
  204. data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
  205. data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
  206. data/entry_types/scrolled/package/frontend/{ToggleFullscreenCornerButton-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
  207. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
  208. data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
  209. data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
  210. data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
  211. data/entry_types/scrolled/package/frontend/{Viewer-0345ce57.js → Viewer-cc8d4072.js} +84 -92
  212. data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
  213. data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
  214. data/entry_types/scrolled/package/frontend/commenting.css +1 -0
  215. data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
  216. data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
  217. data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
  218. data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
  219. data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
  220. data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
  221. data/entry_types/scrolled/package/frontend/{index-eb670c2f.js → index-2e5546f7.js} +36 -44
  222. data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
  223. data/entry_types/scrolled/package/frontend/index.css +1 -1
  224. data/entry_types/scrolled/package/frontend/index.js +1870 -875
  225. data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
  226. data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
  227. data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
  228. data/entry_types/scrolled/package/frontend/{usePhonePlatform-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
  229. data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
  230. data/entry_types/scrolled/package/frontend-server.js +20 -209
  231. data/entry_types/scrolled/package/package.json +5 -3
  232. data/entry_types/scrolled/package/review.css +1 -0
  233. data/entry_types/scrolled/package/review.js +3306 -0
  234. data/entry_types/scrolled/package/testHelpers.js +836 -359
  235. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  236. data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
  237. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  238. data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
  239. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
  240. data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
  241. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  242. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
  243. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
  244. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
  245. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
  246. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  247. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
  248. data/entry_types/scrolled/package/widgets-server.js +1 -0
  249. data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
  250. data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
  251. data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
  252. data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
  253. data/lib/generators/pageflow/resque/resque_generator.rb +0 -2
  254. data/lib/pageflow/configuration.rb +49 -7
  255. data/lib/pageflow/deprecation.rb +19 -0
  256. data/lib/pageflow/engine.rb +1 -1
  257. data/lib/pageflow/entries_controller_env_helper.rb +32 -2
  258. data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
  259. data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
  260. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
  261. data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
  262. data/lib/pageflow/entry_structured_data_types.rb +43 -0
  263. data/lib/pageflow/entry_type_configuration.rb +1 -0
  264. data/lib/pageflow/file_type.rb +2 -2
  265. data/lib/pageflow/file_types.rb +1 -1
  266. data/lib/pageflow/oembed_providers.rb +42 -0
  267. data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
  268. data/lib/pageflow/rails_version.rb +13 -2
  269. data/lib/pageflow/themes.rb +41 -0
  270. data/lib/pageflow/user_mixin.rb +12 -0
  271. data/lib/pageflow/version.rb +1 -1
  272. data/lib/pageflow.rb +1 -0
  273. data/package/config/eslint-rules/documented-in-toc.js +125 -0
  274. data/package/config/jest/index.js +0 -1
  275. data/package/config/webpack.js +0 -1
  276. data/package/config/webpack5.js +0 -1
  277. data/package/editor.js +4378 -1897
  278. data/package/frontend.js +647 -886
  279. data/package/package.json +2 -1
  280. data/package/review.js +384 -0
  281. data/package/testHelpers.js +248 -188
  282. data/package/ui.js +1346 -630
  283. data/package/vendor/stubs/wysihtml5.js +2 -0
  284. data/spec/factories/comment_thread_reads.rb +10 -0
  285. data/spec/factories/comment_threads.rb +10 -0
  286. data/spec/factories/comments.rb +9 -0
  287. data/spec/factories/file_folders.rb +8 -0
  288. data/spec/factories/published_entries.rb +2 -0
  289. metadata +188 -67
  290. data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
  291. data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
  292. data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
  293. data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
  294. data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
  295. data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
  296. data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
  297. data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
  298. data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
  299. data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
  300. data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
  301. data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
  302. data/package/vendor/jquery.minicolors.js +0 -1108
@@ -1,8 +1,9 @@
1
1
  import I18n from 'i18n-js';
2
- import { editor, InlineFileRightsMenuItem, ImageModifierListInputView, EditMotifAreaDialogView, buttonStyles, dialogViewStyles, dialogView } from 'pageflow-scrolled/editor';
3
- import { contentElementWidths, utils, paletteColor } from 'pageflow-scrolled/frontend';
4
- import { SelectInputView, SeparatorView, CheckBoxInputView, LabelOnlyView, ColorInputView, UrlInputView, TextInputView, SliderInputView, ConfigurationEditorView, cssModulesUtils, TabsView, inputView, NumberInputView } from 'pageflow/ui';
5
- import { InfoBoxView, FileInputView, CheckBoxInputView as CheckBoxInputView$1, ColorInputView as ColorInputView$1, editor as editor$1, transientReferences, ListView, cssModulesUtils as cssModulesUtils$1, app, SelectInputView as SelectInputView$1, SeparatorView as SeparatorView$1, SliderInputView as SliderInputView$1, EnumTableCellView } from 'pageflow/editor';
2
+ import { editor, InlineFileRightsMenuItem, ImageModifierListInputView, EditMotifAreaDialogView, buttonStyles, dialogViewStyles, dialogView, PlaybackStartSelectInputView, ScrollRangeSelectInputView } from 'pageflow-scrolled/editor';
3
+ import { contentElementWidths, utils, processImageModifiers, paletteColor } from 'pageflow-scrolled/frontend';
4
+ import { SelectInputView, SeparatorView, CheckBoxInputView, LabelOnlyView, ColorInputView, UrlInputView, TextInputView, SliderInputView, cssModulesUtils, TabsView, inputView, NumberInputView } from 'pageflow/ui';
5
+ import { InfoBoxView, FileInputView, CheckBoxInputView as CheckBoxInputView$1, ColorInputView as ColorInputView$1, EditConfigurationView, DestroyMenuItem, transientReferences, ListView, cssModulesUtils as cssModulesUtils$1, app, SelectInputView as SelectInputView$1, SeparatorView as SeparatorView$1, SliderInputView as SliderInputView$1, EnumTableCellView, editor as editor$1, UploadableFile, altMetaDataAttribute, altConfigurationEditorInput, OembedUrlInputView } from 'pageflow/editor';
6
+ import { Point, Node } from 'slate';
6
7
  import Backbone from 'backbone';
7
8
  import Marionette from 'backbone.marionette';
8
9
  import _ from 'underscore';
@@ -10,55 +11,9 @@ import React, { useReducer, useEffect, useRef } from 'react';
10
11
  import ReactDOM from 'react-dom';
11
12
  import classNames from 'classnames';
12
13
  import { DraggableCore } from 'react-draggable';
13
-
14
- function _defineProperty(obj, key, value) {
15
- if (key in obj) {
16
- Object.defineProperty(obj, key, {
17
- value: value,
18
- enumerable: true,
19
- configurable: true,
20
- writable: true
21
- });
22
- } else {
23
- obj[key] = value;
24
- }
25
-
26
- return obj;
27
- }
28
-
29
- function ownKeys(object, enumerableOnly) {
30
- var keys = Object.keys(object);
31
-
32
- if (Object.getOwnPropertySymbols) {
33
- var symbols = Object.getOwnPropertySymbols(object);
34
- if (enumerableOnly) symbols = symbols.filter(function (sym) {
35
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
36
- });
37
- keys.push.apply(keys, symbols);
38
- }
39
-
40
- return keys;
41
- }
42
-
43
- function _objectSpread2(target) {
44
- for (var i = 1; i < arguments.length; i++) {
45
- var source = arguments[i] != null ? arguments[i] : {};
46
-
47
- if (i % 2) {
48
- ownKeys(Object(source), true).forEach(function (key) {
49
- _defineProperty(target, key, source[key]);
50
- });
51
- } else if (Object.getOwnPropertyDescriptors) {
52
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
53
- } else {
54
- ownKeys(Object(source)).forEach(function (key) {
55
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
56
- });
57
- }
58
- }
59
-
60
- return target;
61
- }
14
+ import { DotLottie } from '@lottiefiles/dotlottie-web';
15
+ import wasmUrl from '@lottiefiles/dotlottie-web/dotlottie-player.wasm';
16
+ import { review } from 'pageflow-scrolled/review';
62
17
 
63
18
  var img = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3e%3c!--! Font Awesome Pro 6.1.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons%2c Inc. --%3e%3cpath fill='white' d='M448 448c0 17.69-14.33 32-32 32h-96c-17.67 0-32-14.31-32-32s14.33-32 32-32h16v-144h-224v144H128c17.67 0 32 14.31 32 32s-14.33 32-32 32H32c-17.67 0-32-14.31-32-32s14.33-32 32-32h16v-320H32c-17.67 0-32-14.31-32-32s14.33-32 32-32h96c17.67 0 32 14.31 32 32s-14.33 32-32 32H112v112h224v-112H320c-17.67 0-32-14.31-32-32s14.33-32 32-32h96c17.67 0 32 14.31 32 32s-14.33 32-32 32h-16v320H416C433.7 416 448 430.3 448 448z'/%3e%3c/svg%3e";
64
19
 
@@ -70,29 +25,34 @@ editor.contentElementTypes.register('heading', {
70
25
  width: contentElementWidths.xl,
71
26
  marginTop: 'none'
72
27
  },
73
- configurationEditor: function configurationEditor(_ref) {
74
- var entry = _ref.entry;
28
+ defaultsInputs() {
29
+ this.input('hyphens', SelectInputView, {
30
+ values: ['auto', 'manual']
31
+ });
32
+ },
33
+ configurationEditor({
34
+ entry
35
+ }) {
75
36
  this.listenTo(this.model, 'change:hyphens', this.refresh);
76
- var modelDelegator = entry.createLegacyTypographyVariantDelegator({
37
+ const modelDelegator = entry.createLegacyTypographyVariantDelegator({
77
38
  model: this.model,
78
39
  paletteColorPropertyName: 'color'
79
40
  });
80
41
  this.tab('general', function () {
81
42
  this.group('ContentElementTypographyVariant', {
82
- entry: entry,
43
+ entry,
83
44
  model: modelDelegator,
84
- getPreviewConfiguration: function getPreviewConfiguration(configuration, typographyVariant) {
85
- return _objectSpread2(_objectSpread2({}, configuration), {}, {
86
- textSize: 'small',
87
- typographyVariant: typographyVariant
88
- });
89
- }
45
+ getPreviewConfiguration: (configuration, typographyVariant) => ({
46
+ ...configuration,
47
+ textSize: 'small',
48
+ typographyVariant
49
+ })
90
50
  });
91
51
  this.input('textSize', SelectInputView, {
92
52
  values: ['auto', 'large', 'medium', 'small']
93
53
  });
94
54
  this.group('PaletteColor', {
95
- entry: entry,
55
+ entry,
96
56
  model: modelDelegator,
97
57
  propertyName: 'color'
98
58
  });
@@ -109,7 +69,7 @@ editor.contentElementTypes.register('heading', {
109
69
  }
110
70
  this.view(SeparatorView);
111
71
  this.group('ContentElementPosition', {
112
- entry: entry
72
+ entry
113
73
  });
114
74
  });
115
75
  }
@@ -120,42 +80,36 @@ var img$1 = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBo
120
80
  editor.contentElementTypes.register('textBlock', {
121
81
  pictogram: img$1,
122
82
  supportedPositions: ['inline'],
123
- configurationEditor: function configurationEditor(_ref) {
124
- var _this = this;
125
- var entry = _ref.entry,
126
- contentElement = _ref.contentElement;
127
- var pendingRefresh;
128
- this.listenTo(contentElement.transientState, 'change:exampleNode', function () {
129
- // This is a terrible hack to prevent closing the minicolors
130
- // dropdown while adjusting colors. Calling refresh is needed
131
- // to update typography drop downs. Delay until color picker
132
- // is closed.
133
- if (document.activeElement && document.activeElement.tagName === 'INPUT' && document.activeElement.className === 'minicolors-input') {
134
- if (!pendingRefresh) {
135
- document.activeElement.addEventListener('blur', function () {
136
- pendingRefresh = false;
137
- _this.refresh();
138
- }, {
139
- once: true
140
- });
141
- pendingRefresh = true;
142
- }
143
- return;
83
+ configurationEditor({
84
+ entry,
85
+ contentElement
86
+ }) {
87
+ var _contentElement$trans;
88
+ let lastExampleNodeType = (_contentElement$trans = contentElement.transientState.get('exampleNode')) === null || _contentElement$trans === void 0 ? void 0 : _contentElement$trans.type;
89
+ this.listenTo(contentElement.transientState, 'change:exampleNode', () => {
90
+ var _contentElement$trans2;
91
+ const exampleNodeType = (_contentElement$trans2 = contentElement.transientState.get('exampleNode')) === null || _contentElement$trans2 === void 0 ? void 0 : _contentElement$trans2.type;
92
+ if (exampleNodeType !== lastExampleNodeType) {
93
+ lastExampleNodeType = exampleNodeType;
94
+ this.refresh();
144
95
  }
145
- _this.refresh();
146
96
  });
147
97
  this.tab('general', function () {
148
- var exampleNode = ensureTextContent(contentElement.transientState.get('exampleNode'));
149
- var modelDelegator = entry.createLegacyTypographyVariantDelegator({
98
+ const exampleNode = contentElement.transientState.get('exampleNode');
99
+ const modelDelegator = entry.createLegacyTypographyVariantDelegator({
150
100
  model: contentElement.transientState,
151
101
  paletteColorPropertyName: 'color'
152
102
  });
153
- var _getPreviewConfiguration = function getPreviewConfiguration(configuration, properties) {
154
- return exampleNode ? _objectSpread2(_objectSpread2({}, configuration), {}, {
155
- value: [_objectSpread2(_objectSpread2({}, exampleNode), {}, {
103
+ const getPreviewConfiguration = (configuration, properties) => {
104
+ const currentExampleNode = ensureTextContent(contentElement.transientState.get('exampleNode'));
105
+ return currentExampleNode ? {
106
+ ...configuration,
107
+ value: [{
108
+ ...currentExampleNode,
156
109
  // Ensure size in preview is not overridden by legacy variant
157
- variant: modelDelegator.get('typographyVariant')
158
- }, properties),
110
+ variant: modelDelegator.get('typographyVariant'),
111
+ ...properties
112
+ },
159
113
  // Ensure content spans whole preview viewport if
160
114
  // section uses "cards" appearance.
161
115
  {
@@ -169,30 +123,34 @@ editor.contentElementTypes.register('textBlock', {
169
123
  text: ''
170
124
  }]
171
125
  }]
172
- }) : configuration;
126
+ } : configuration;
173
127
  };
174
128
  this.group('ContentElementTypographyVariant', {
175
- entry: entry,
129
+ entry,
176
130
  model: modelDelegator,
177
131
  prefix: exampleNode ? utils.camelize(exampleNode.type) : 'none',
178
- getPreviewConfiguration: function getPreviewConfiguration(configuration, variant) {
179
- return _getPreviewConfiguration(configuration, {
180
- variant: variant
132
+ previewConfigurationBindingModel: contentElement.transientState,
133
+ previewConfigurationBinding: 'exampleNode',
134
+ getPreviewConfiguration(configuration, variant) {
135
+ return getPreviewConfiguration(configuration, {
136
+ variant
181
137
  });
182
138
  }
183
139
  });
184
140
  this.group('ContentElementTypographySize', {
185
- entry: entry,
141
+ entry,
186
142
  model: modelDelegator,
187
143
  prefix: exampleNode ? utils.camelize(exampleNode.type) : 'none',
188
- getPreviewConfiguration: function getPreviewConfiguration(configuration, size) {
189
- return _getPreviewConfiguration(configuration, {
190
- size: size
144
+ previewConfigurationBindingModel: contentElement.transientState,
145
+ previewConfigurationBinding: 'exampleNode',
146
+ getPreviewConfiguration(configuration, size) {
147
+ return getPreviewConfiguration(configuration, {
148
+ size
191
149
  });
192
150
  }
193
151
  });
194
152
  this.group('PaletteColor', {
195
- entry: entry,
153
+ entry,
196
154
  model: modelDelegator,
197
155
  propertyName: 'color'
198
156
  });
@@ -206,31 +164,90 @@ editor.contentElementTypes.register('textBlock', {
206
164
  });
207
165
  });
208
166
  },
209
- split: function split(configuration, insertIndex) {
210
- var value = getValue(configuration);
211
- return [_objectSpread2(_objectSpread2({}, configuration), {}, {
212
- value: value.slice(0, insertIndex)
213
- }), _objectSpread2(_objectSpread2({}, configuration), {}, {
214
- value: value.slice(insertIndex)
215
- })];
167
+ split(configuration, at, {
168
+ ranges
169
+ }) {
170
+ const value = getValue(configuration);
171
+ const beforeValue = value.slice(0, at);
172
+ const afterValue = value.slice(at);
173
+ const beforeRanges = {};
174
+ const afterRanges = {};
175
+ Object.entries(ranges).forEach(([id, range]) => {
176
+ const startPath = Math.min(range.anchor.path[0], range.focus.path[0]);
177
+ const endPath = Math.max(range.anchor.path[0], range.focus.path[0]);
178
+ if (endPath < at) {
179
+ beforeRanges[id] = range;
180
+ } else if (startPath >= at) {
181
+ afterRanges[id] = shiftRange(range, -at);
182
+ } else {
183
+ const start = Point.isBefore(range.anchor, range.focus) ? range.anchor : range.focus;
184
+ beforeRanges[id] = {
185
+ anchor: start,
186
+ focus: endOfBlock(beforeValue, at - 1)
187
+ };
188
+ }
189
+ });
190
+ return {
191
+ before: {
192
+ configuration: {
193
+ ...configuration,
194
+ value: beforeValue
195
+ },
196
+ ranges: beforeRanges
197
+ },
198
+ after: {
199
+ configuration: {
200
+ ...configuration,
201
+ value: afterValue
202
+ },
203
+ ranges: afterRanges
204
+ }
205
+ };
216
206
  },
217
- merge: function merge(configurationA, configurationB) {
218
- var value = getValue(configurationA).concat(getValue(configurationB));
219
- return _objectSpread2(_objectSpread2({}, configurationA), {}, {
220
- value: value
207
+ merge(configurationA, configurationB, {
208
+ rangesA,
209
+ rangesB
210
+ }) {
211
+ const valueA = getValue(configurationA);
212
+ const valueB = getValue(configurationB);
213
+ const ranges = {
214
+ ...rangesA
215
+ };
216
+ Object.entries(rangesB).forEach(([id, range]) => {
217
+ ranges[id] = shiftRange(range, valueA.length);
221
218
  });
219
+ return {
220
+ configuration: {
221
+ ...configurationA,
222
+ value: valueA.concat(valueB)
223
+ },
224
+ ranges
225
+ };
222
226
  },
223
- getLength: function getLength(configuration) {
227
+ getLength(configuration) {
224
228
  return getValue(configuration).length;
225
229
  },
226
- handleDestroy: function handleDestroy(contentElement) {
227
- var transientState = contentElement.get('transientState') || {};
230
+ handleDestroy(contentElement) {
231
+ const transientState = contentElement.get('transientState') || {};
228
232
  if (!transientState.editableTextIsSingleBlock) {
229
233
  contentElement.postCommand({
230
234
  type: 'REMOVE'
231
235
  });
232
236
  return false;
233
237
  }
238
+ },
239
+ handleDuplicate(contentElement) {
240
+ contentElement.postCommand({
241
+ type: 'DUPLICATE'
242
+ });
243
+ },
244
+ handleMove(contentElement, to) {
245
+ contentElement.postCommand({
246
+ type: 'MOVE_TO',
247
+ payload: {
248
+ to
249
+ }
250
+ });
234
251
  }
235
252
  });
236
253
  function getValue(configuration) {
@@ -242,13 +259,35 @@ function getValue(configuration) {
242
259
  }]
243
260
  }];
244
261
  }
262
+ function shiftRange(range, delta) {
263
+ return {
264
+ anchor: shiftPoint(range.anchor, delta),
265
+ focus: shiftPoint(range.focus, delta)
266
+ };
267
+ }
268
+ function shiftPoint(point, delta) {
269
+ return {
270
+ ...point,
271
+ path: [point.path[0] + delta, ...point.path.slice(1)]
272
+ };
273
+ }
274
+ function endOfBlock(value, blockIndex) {
275
+ const [lastNode, lastPath] = Node.last({
276
+ children: value
277
+ }, [blockIndex]);
278
+ return {
279
+ path: lastPath,
280
+ offset: lastNode.text.length
281
+ };
282
+ }
245
283
  function ensureTextContent(node) {
246
284
  if (node && node.children.length === 1 && node.children[0].text === '') {
247
- return _objectSpread2(_objectSpread2({}, node), {}, {
285
+ return {
286
+ ...node,
248
287
  children: [{
249
288
  text: 'Lorem ipsum dolor sit amet'
250
289
  }]
251
- });
290
+ };
252
291
  } else {
253
292
  return node;
254
293
  }
@@ -261,155 +300,94 @@ editor.contentElementTypes.register('inlineImage', {
261
300
  category: 'media',
262
301
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
263
302
  supportedWidthRange: ['xxs', 'full'],
264
- configurationEditor: function configurationEditor(_ref) {
265
- var entry = _ref.entry,
266
- contentElement = _ref.contentElement;
303
+ supportedCaptions: true,
304
+ supportedStyles: ['boxShadow', 'outline'],
305
+ defaultsInputs() {
306
+ this.input('enableFullscreen', CheckBoxInputView);
307
+ },
308
+ configurationEditor({
309
+ entry,
310
+ contentElement
311
+ }) {
267
312
  this.tab('general', function () {
268
- var _this = this;
269
313
  this.input('id', FileInputView, {
270
314
  collection: 'image_files',
271
315
  fileSelectionHandler: 'contentElementConfiguration',
272
- positioning: function positioning(imageModifiers) {
273
- return imageModifiers === null || imageModifiers === void 0 ? void 0 : imageModifiers.length;
274
- },
316
+ positioning: imageModifiers => !!processImageModifiers(imageModifiers).aspectRatio,
275
317
  positioningBinding: 'imageModifiers',
276
- positioningOptions: function positioningOptions() {
277
- var _this$model$get, _this$model$get$;
278
- var aspectRatio = entry.getAspectRatio((_this$model$get = _this.model.get('imageModifiers')) === null || _this$model$get === void 0 ? void 0 : (_this$model$get$ = _this$model$get[0]) === null || _this$model$get$ === void 0 ? void 0 : _this$model$get$.value);
318
+ positioningOptions: () => {
319
+ const {
320
+ aspectRatio
321
+ } = processImageModifiers(this.model.get('imageModifiers'));
279
322
  return {
280
- preview: aspectRatio && 1 / aspectRatio
323
+ preview: aspectRatio && 1 / entry.getAspectRatio(aspectRatio)
281
324
  };
282
325
  },
283
326
  dropDownMenuItems: [InlineFileRightsMenuItem]
284
327
  });
285
328
  this.input('imageModifiers', ImageModifierListInputView, {
286
- entry: entry,
329
+ entry,
287
330
  visibleBinding: 'id',
288
- visible: function visible() {
289
- return _this.model.getReference('id', 'image_files');
290
- }
331
+ visible: () => this.model.getReference('id', 'image_files')
291
332
  });
292
333
  this.input('portraitId', FileInputView, {
293
334
  collection: 'image_files',
294
335
  fileSelectionHandler: 'contentElementConfiguration',
295
- positioning: function positioning(imageModifiers) {
296
- return imageModifiers === null || imageModifiers === void 0 ? void 0 : imageModifiers.length;
297
- },
336
+ positioning: imageModifiers => !!processImageModifiers(imageModifiers).aspectRatio,
298
337
  positioningBinding: 'portraitImageModifiers',
299
- positioningOptions: function positioningOptions() {
300
- var _this$model$get2, _this$model$get2$;
301
- var aspectRatio = entry.getAspectRatio((_this$model$get2 = _this.model.get('portraitImageModifiers')) === null || _this$model$get2 === void 0 ? void 0 : (_this$model$get2$ = _this$model$get2[0]) === null || _this$model$get2$ === void 0 ? void 0 : _this$model$get2$.value);
338
+ positioningOptions: () => {
339
+ const {
340
+ aspectRatio
341
+ } = processImageModifiers(this.model.get('portraitImageModifiers'));
302
342
  return {
303
- preview: aspectRatio && 1 / aspectRatio
343
+ preview: aspectRatio && 1 / entry.getAspectRatio(aspectRatio)
304
344
  };
305
345
  }
306
346
  });
307
347
  this.input('portraitImageModifiers', ImageModifierListInputView, {
308
- entry: entry,
348
+ entry,
309
349
  visibleBinding: 'portraitId',
310
- visible: function visible() {
311
- return _this.model.getReference('portraitId', 'image_files');
312
- }
350
+ visible: () => this.model.getReference('portraitId', 'image_files')
313
351
  });
314
352
  this.input('enableFullscreen', CheckBoxInputView, {
315
353
  disabledBinding: ['position', 'width'],
316
- disabled: function disabled() {
317
- return contentElement.getWidth() === contentElementWidths.full;
318
- },
354
+ disabled: () => contentElement.getWidth() === contentElementWidths.full,
319
355
  displayUncheckedIfDisabled: true
320
356
  });
321
357
  this.group('ContentElementPosition', {
322
- entry: entry
358
+ entry
323
359
  });
324
360
  this.view(SeparatorView);
325
361
  this.group('ContentElementCaption', {
326
- entry: entry
362
+ entry
327
363
  });
328
364
  this.group('ContentElementInlineFileRightsSettings');
329
365
  });
330
366
  }
331
367
  });
332
368
 
333
- function _arrayWithHoles(arr) {
334
- if (Array.isArray(arr)) return arr;
335
- }
336
-
337
- function _iterableToArrayLimit(arr, i) {
338
- if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
339
- var _arr = [];
340
- var _n = true;
341
- var _d = false;
342
- var _e = undefined;
343
-
344
- try {
345
- for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
346
- _arr.push(_s.value);
347
-
348
- if (i && _arr.length === i) break;
349
- }
350
- } catch (err) {
351
- _d = true;
352
- _e = err;
353
- } finally {
354
- try {
355
- if (!_n && _i["return"] != null) _i["return"]();
356
- } finally {
357
- if (_d) throw _e;
358
- }
359
- }
360
-
361
- return _arr;
362
- }
363
-
364
- function _arrayLikeToArray(arr, len) {
365
- if (len == null || len > arr.length) len = arr.length;
366
-
367
- for (var i = 0, arr2 = new Array(len); i < len; i++) {
368
- arr2[i] = arr[i];
369
- }
370
-
371
- return arr2;
372
- }
373
-
374
- function _unsupportedIterableToArray(o, minLen) {
375
- if (!o) return;
376
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
377
- var n = Object.prototype.toString.call(o).slice(8, -1);
378
- if (n === "Object" && o.constructor) n = o.constructor.name;
379
- if (n === "Map" || n === "Set") return Array.from(n);
380
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
381
- }
382
-
383
- function _nonIterableRest() {
384
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
385
- }
386
-
387
- function _slicedToArray(arr, i) {
388
- return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
389
- }
390
-
391
369
  var img$3 = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3c!--! Font Awesome Pro 6.1.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons%2c Inc. --%3e%3cpath fill='white' d='M463.1 32h-416C21.49 32-.0001 53.49-.0001 80v352c0 26.51 21.49 48 47.1 48h416c26.51 0 48-21.49 48-48v-352C511.1 53.49 490.5 32 463.1 32zM111.1 408c0 4.418-3.582 8-8 8H55.1c-4.418 0-8-3.582-8-8v-48c0-4.418 3.582-8 8-8h47.1c4.418 0 8 3.582 8 8L111.1 408zM111.1 280c0 4.418-3.582 8-8 8H55.1c-4.418 0-8-3.582-8-8v-48c0-4.418 3.582-8 8-8h47.1c4.418 0 8 3.582 8 8V280zM111.1 152c0 4.418-3.582 8-8 8H55.1c-4.418 0-8-3.582-8-8v-48c0-4.418 3.582-8 8-8h47.1c4.418 0 8 3.582 8 8L111.1 152zM351.1 400c0 8.836-7.164 16-16 16H175.1c-8.836 0-16-7.164-16-16v-96c0-8.838 7.164-16 16-16h160c8.836 0 16 7.162 16 16V400zM351.1 208c0 8.836-7.164 16-16 16H175.1c-8.836 0-16-7.164-16-16v-96c0-8.838 7.164-16 16-16h160c8.836 0 16 7.162 16 16V208zM463.1 408c0 4.418-3.582 8-8 8h-47.1c-4.418 0-7.1-3.582-7.1-8l0-48c0-4.418 3.582-8 8-8h47.1c4.418 0 8 3.582 8 8V408zM463.1 280c0 4.418-3.582 8-8 8h-47.1c-4.418 0-8-3.582-8-8v-48c0-4.418 3.582-8 8-8h47.1c4.418 0 8 3.582 8 8V280zM463.1 152c0 4.418-3.582 8-8 8h-47.1c-4.418 0-8-3.582-8-8l0-48c0-4.418 3.582-8 7.1-8h47.1c4.418 0 8 3.582 8 8V152z'/%3e%3c/svg%3e";
392
370
 
393
- var EditMotifAreaMenuItem = Backbone.Model.extend({
371
+ const EditMotifAreaMenuItem = Backbone.Model.extend({
394
372
  defaults: {
395
373
  name: 'editMotifArea'
396
374
  },
397
- initialize: function initialize(attributes, _ref) {
398
- var _this = this;
399
- var inputModel = _ref.inputModel,
400
- propertyName = _ref.propertyName,
401
- file = _ref.file;
375
+ initialize(attributes, {
376
+ inputModel,
377
+ propertyName,
378
+ file
379
+ }) {
402
380
  this.set('label', I18n.t('pageflow_scrolled.editor.edit_motif_area_menu_item'));
403
- var update = function update() {
404
- _this.set('hidden', inputModel.get('position') !== 'backdrop');
381
+ const update = () => {
382
+ this.set('hidden', inputModel.get('position') !== 'backdrop');
405
383
  };
406
- this.listenTo(inputModel, "change:position", update);
384
+ this.listenTo(inputModel, `change:position`, update);
407
385
  update();
408
- this.selected = function () {
386
+ this.selected = () => {
409
387
  EditMotifAreaDialogView.show({
410
388
  model: inputModel,
411
- propertyName: propertyName,
412
- file: file
389
+ propertyName,
390
+ file
413
391
  });
414
392
  };
415
393
  }
@@ -419,15 +397,32 @@ editor.contentElementTypes.register('inlineVideo', {
419
397
  category: 'media',
420
398
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right', 'backdrop'],
421
399
  supportedWidthRange: ['xxs', 'full'],
422
- configurationEditor: function configurationEditor(_ref2) {
423
- var entry = _ref2.entry;
400
+ supportedCaptions: true,
401
+ supportedStyles: ['boxShadow', 'outline'],
402
+ defaultsInputs() {
403
+ this.input('playbackMode', SelectInputView, {
404
+ values: ['manual', 'autoplay', 'autoplayIfUnmuted', 'loop']
405
+ });
406
+ this.input('enableFullscreen', CheckBoxInputView$1);
407
+ },
408
+ configurationEditor({
409
+ entry
410
+ }) {
424
411
  migrateLegacyAutoplay(this.model);
425
412
  this.tab('general', function () {
426
- var _this2 = this;
427
413
  this.input('id', FileInputView, {
428
414
  collection: 'video_files',
429
415
  fileSelectionHandler: 'contentElementConfiguration',
430
- positioning: false,
416
+ positioning: imageModifiers => !!processImageModifiers(imageModifiers).aspectRatio,
417
+ positioningBinding: 'imageModifiers',
418
+ positioningOptions: () => {
419
+ const {
420
+ aspectRatio
421
+ } = processImageModifiers(this.model.get('imageModifiers'));
422
+ return {
423
+ preview: aspectRatio && 1 / entry.getAspectRatio(aspectRatio)
424
+ };
425
+ },
431
426
  defaultTextTrackFilePropertyName: 'defaultTextTrackFileId',
432
427
  dropDownMenuItems: [EditMotifAreaMenuItem, InlineFileRightsMenuItem]
433
428
  });
@@ -437,10 +432,24 @@ editor.contentElementTypes.register('inlineVideo', {
437
432
  positioning: false,
438
433
  dropDownMenuItems: [InlineFileRightsMenuItem]
439
434
  });
435
+ this.input('imageModifiers', ImageModifierListInputView, {
436
+ entry,
437
+ visibleBinding: 'id',
438
+ visible: () => this.model.getReference('id', 'video_files')
439
+ });
440
440
  this.input('portraitId', FileInputView, {
441
441
  collection: 'video_files',
442
442
  fileSelectionHandler: 'contentElementConfiguration',
443
- positioning: false,
443
+ positioning: imageModifiers => !!processImageModifiers(imageModifiers).aspectRatio,
444
+ positioningBinding: 'portraitImageModifiers',
445
+ positioningOptions: () => {
446
+ const {
447
+ aspectRatio
448
+ } = processImageModifiers(this.model.get('portraitImageModifiers'));
449
+ return {
450
+ preview: aspectRatio && 1 / entry.getAspectRatio(aspectRatio)
451
+ };
452
+ },
444
453
  defaultTextTrackFilePropertyName: 'defaultTextTrackFileId',
445
454
  dropDownMenuItems: [EditMotifAreaMenuItem, InlineFileRightsMenuItem]
446
455
  });
@@ -449,20 +458,21 @@ editor.contentElementTypes.register('inlineVideo', {
449
458
  fileSelectionHandler: 'contentElementConfiguration',
450
459
  positioning: false,
451
460
  visibleBinding: 'portraitId',
452
- visible: function visible() {
453
- return _this2.model.getReference('portraitId', 'video_files');
454
- },
461
+ visible: () => this.model.getReference('portraitId', 'video_files'),
455
462
  dropDownMenuItems: [InlineFileRightsMenuItem]
456
463
  });
464
+ this.input('portraitImageModifiers', ImageModifierListInputView, {
465
+ entry,
466
+ visibleBinding: 'portraitId',
467
+ visible: () => this.model.getReference('portraitId', 'video_files')
468
+ });
457
469
  this.view(SeparatorView);
458
470
  this.input('playbackMode', SelectInputView, {
459
- values: ['manual', 'autoplay', 'loop']
471
+ values: ['manual', 'autoplay', 'autoplayIfUnmuted', 'loop']
460
472
  });
461
473
  this.input('hideControlBar', CheckBoxInputView$1, {
462
- disabledBinding: 'playbackMode',
463
- disabled: function disabled(playbackMode) {
464
- return playbackMode === 'loop';
465
- },
474
+ disabledBinding: ['playbackMode', 'imageModifiers'],
475
+ disabled: ([playbackMode, imageModifiers]) => playbackMode === 'loop' || processImageModifiers(imageModifiers).rounded === 'circle',
466
476
  displayCheckedIfDisabled: true
467
477
  });
468
478
  this.input('unmuteLabel', LabelOnlyView);
@@ -471,12 +481,7 @@ editor.contentElementTypes.register('inlineVideo', {
471
481
  });
472
482
  this.input('rewindOnUnmute', CheckBoxInputView$1, {
473
483
  disabledBinding: ['playbackMode', 'keepMuted'],
474
- disabled: function disabled(_ref3) {
475
- var _ref4 = _slicedToArray(_ref3, 2),
476
- playbackMode = _ref4[0],
477
- keepMuted = _ref4[1];
478
- return playbackMode !== 'autoplay' || keepMuted;
479
- },
484
+ disabled: ([playbackMode, keepMuted]) => playbackMode !== 'autoplay' || keepMuted,
480
485
  displayUncheckedIfDisabled: true
481
486
  });
482
487
  this.view(SeparatorView);
@@ -484,12 +489,17 @@ editor.contentElementTypes.register('inlineVideo', {
484
489
  values: ['play', 'mute', 'turnDown']
485
490
  });
486
491
  this.view(SeparatorView);
492
+ this.input('enableFullscreen', CheckBoxInputView$1, {
493
+ disabledBinding: ['position', 'playbackMode'],
494
+ disabled: ([position, playbackMode]) => position === 'backdrop' || playbackMode === 'loop',
495
+ displayUncheckedIfDisabled: true
496
+ });
487
497
  this.group('ContentElementPosition', {
488
- entry: entry
498
+ entry
489
499
  });
490
500
  this.view(SeparatorView);
491
501
  this.group('ContentElementCaption', {
492
- entry: entry
502
+ entry
493
503
  });
494
504
  this.group('ContentElementInlineFileRightsSettings');
495
505
  });
@@ -503,6 +513,11 @@ function migrateLegacyAutoplay(model) {
503
513
  }
504
514
  }
505
515
 
516
+ const defaultRemainingWaveformColor = '#828282ed';
517
+ const defaultRemainingWaveformColorInverted = 'rgba(0, 0, 0, 0.5)';
518
+ const defaultWaveformCursorColor = '#fff';
519
+ const defaultWaveformCursorColorInverted = '#888';
520
+
506
521
  var img$4 = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3e%3c!--! Font Awesome Pro 6.1.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons%2c Inc. --%3e%3cpath fill='white' d='M192 352c53.03 0 96-42.97 96-96v-160c0-53.03-42.97-96-96-96s-96 42.97-96 96v160C96 309 138.1 352 192 352zM344 192C330.7 192 320 202.7 320 215.1V256c0 73.33-61.97 132.4-136.3 127.7c-66.08-4.169-119.7-66.59-119.7-132.8L64 215.1C64 202.7 53.25 192 40 192S16 202.7 16 215.1v32.15c0 89.66 63.97 169.6 152 181.7V464H128c-18.19 0-32.84 15.18-31.96 33.57C96.43 505.8 103.8 512 112 512h160c8.222 0 15.57-6.216 15.96-14.43C288.8 479.2 274.2 464 256 464h-40v-33.77C301.7 418.5 368 344.9 368 256V215.1C368 202.7 357.3 192 344 192z'/%3e%3c/svg%3e";
507
522
 
508
523
  editor.contentElementTypes.register('inlineAudio', {
@@ -510,14 +525,33 @@ editor.contentElementTypes.register('inlineAudio', {
510
525
  category: 'media',
511
526
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
512
527
  supportedWidthRange: ['xxs', 'full'],
528
+ supportedCaptions: true,
529
+ supportedStyles: [{
530
+ name: 'boxShadow',
531
+ when: posterId => !!posterId,
532
+ binding: 'posterId'
533
+ }, {
534
+ name: 'outline',
535
+ when: posterId => !!posterId,
536
+ binding: 'posterId'
537
+ }],
513
538
  defaultConfig: {
514
539
  playerControlVariant: 'waveformBars'
515
540
  },
516
- configurationEditor: function configurationEditor(_ref) {
517
- var entry = _ref.entry;
518
- var themeOptions = entry.getTheme().get('options');
541
+ defaultsInputs() {
542
+ this.input('autoplay', CheckBoxInputView$1);
543
+ this.input('playerControlVariant', SelectInputView, {
544
+ values: ['waveformBars', 'waveformLines', 'waveform', 'classic']
545
+ });
546
+ },
547
+ configurationEditor({
548
+ entry,
549
+ contentElement
550
+ }) {
551
+ const themeProperties = entry.getThemeProperties();
552
+ const invert = contentElement.section.configuration.get('invert');
519
553
  this.tab('general', function () {
520
- var _themeOptions$propert, _themeOptions$propert2, _themeOptions$colors;
554
+ var _themeProperties$root, _themeProperties$colo;
521
555
  this.input('id', FileInputView, {
522
556
  collection: 'audio_files',
523
557
  fileSelectionHandler: 'contentElementConfiguration',
@@ -542,19 +576,39 @@ editor.contentElementTypes.register('inlineAudio', {
542
576
  ensureValueDefined: true
543
577
  });
544
578
  this.input('waveformColor', ColorInputView, {
579
+ alpha: true,
545
580
  visibleBinding: 'playerControlVariant',
546
- visible: function visible(variant) {
547
- return variant === null || variant === void 0 ? void 0 : variant.startsWith('waveform');
548
- },
549
- defaultValue: ((_themeOptions$propert = themeOptions.properties) === null || _themeOptions$propert === void 0 ? void 0 : (_themeOptions$propert2 = _themeOptions$propert.root) === null || _themeOptions$propert2 === void 0 ? void 0 : _themeOptions$propert2.accent_color) || ((_themeOptions$colors = themeOptions.colors) === null || _themeOptions$colors === void 0 ? void 0 : _themeOptions$colors.accent)
581
+ visible: variant => variant === null || variant === void 0 ? void 0 : variant.startsWith('waveform'),
582
+ defaultValue: ((_themeProperties$root = themeProperties.root) === null || _themeProperties$root === void 0 ? void 0 : _themeProperties$root.accentColor) || ((_themeProperties$colo = themeProperties.colors) === null || _themeProperties$colo === void 0 ? void 0 : _themeProperties$colo.accent),
583
+ swatches: entry.getUsedContentElementColors('waveformColor')
584
+ });
585
+ this.input('remainingWaveformColor', ColorInputView, {
586
+ alpha: true,
587
+ visibleBinding: 'playerControlVariant',
588
+ visible: variant => variant === null || variant === void 0 ? void 0 : variant.startsWith('waveform'),
589
+ placeholder: I18n.t('pageflow_scrolled.editor.content_elements.inlineAudio.attributes.remainingWaveformColor.auto'),
590
+ placeholderColor: invert ? defaultRemainingWaveformColorInverted : defaultRemainingWaveformColor,
591
+ swatches: entry.getUsedContentElementColors('remainingWaveformColor')
592
+ });
593
+ this.input('waveformCursorColor', ColorInputView, {
594
+ alpha: true,
595
+ visibleBinding: 'playerControlVariant',
596
+ visible: variant => variant === null || variant === void 0 ? void 0 : variant.startsWith('waveform'),
597
+ placeholder: I18n.t('pageflow_scrolled.editor.content_elements.inlineAudio.attributes.waveformCursorColor.auto'),
598
+ placeholderColor: invert ? defaultWaveformCursorColorInverted : defaultWaveformCursorColor,
599
+ swatches: entry.getUsedContentElementColors('waveformCursorColor')
600
+ });
601
+ this.input('invertPlayButton', CheckBoxInputView$1, {
602
+ visibleBinding: 'playerControlVariant',
603
+ visible: variant => variant === null || variant === void 0 ? void 0 : variant.startsWith('waveform')
550
604
  });
551
605
  this.view(SeparatorView);
552
606
  this.group('ContentElementPosition', {
553
- entry: entry
607
+ entry
554
608
  });
555
609
  this.view(SeparatorView);
556
610
  this.group('ContentElementCaption', {
557
- entry: entry
611
+ entry
558
612
  });
559
613
  this.group('ContentElementInlineFileRightsSettings');
560
614
  });
@@ -568,8 +622,11 @@ editor.contentElementTypes.register('videoEmbed', {
568
622
  category: 'media',
569
623
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
570
624
  supportedWidthRange: ['xxs', 'full'],
571
- configurationEditor: function configurationEditor(_ref) {
572
- var entry = _ref.entry;
625
+ supportedCaptions: true,
626
+ supportedStyles: ['boxShadow', 'outline'],
627
+ configurationEditor({
628
+ entry
629
+ }) {
573
630
  this.tab('general', function () {
574
631
  this.input('videoSource', UrlInputView, {
575
632
  supportedHosts: ['http://youtu.be', 'https://youtu.be', 'http://www.youtube.com', 'https://www.youtube.com', 'http://vimeo.com', 'https://vimeo.com', 'http://www.facebook.com', 'https://www.facebook.com'],
@@ -593,11 +650,11 @@ editor.contentElementTypes.register('videoEmbed', {
593
650
  });
594
651
  this.view(SeparatorView);
595
652
  this.group('ContentElementPosition', {
596
- entry: entry
653
+ entry
597
654
  });
598
655
  this.view(SeparatorView);
599
656
  this.group('ContentElementCaption', {
600
- entry: entry
657
+ entry
601
658
  });
602
659
  });
603
660
  }
@@ -609,8 +666,9 @@ editor.contentElementTypes.register('soundDisclaimer', {
609
666
  pictogram: img$6,
610
667
  category: 'media',
611
668
  supportedPositions: ['inline'],
612
- configurationEditor: function configurationEditor(_ref) {
613
- var entry = _ref.entry;
669
+ configurationEditor({
670
+ entry
671
+ }) {
614
672
  this.tab('general', function () {
615
673
  this.input('mutedText', TextInputView, {
616
674
  placeholder: I18n.t('pageflow_scrolled.public.sound_disclaimer.help_muted', {
@@ -626,10 +684,13 @@ editor.contentElementTypes.register('soundDisclaimer', {
626
684
  }
627
685
  });
628
686
 
629
- var DatawrapperAdView = Marionette.ItemView.extend({
630
- template: function template(data) {
631
- return "\n <form action=\"https://app.datawrapper.de/create/chart\" method=\"GET\" target=\"_blank\">\n <input type=\"hidden\" name=\"theme\" value=\"pageflow\" />\n <input type=\"submit\" value=\"".concat(I18n.t('pageflow_scrolled.editor.content_elements.dataWrapperChart.attributes.create_chart.label'), "\" />\n </form>\n ");
632
- },
687
+ const DatawrapperAdView = Marionette.ItemView.extend({
688
+ template: data => `
689
+ <form action="https://app.datawrapper.de/create/chart" method="GET" target="_blank">
690
+ <input type="hidden" name="theme" value="pageflow" />
691
+ <input type="submit" value="${I18n.t('pageflow_scrolled.editor.content_elements.dataWrapperChart.attributes.create_chart.label')}" />
692
+ </form>
693
+ `,
633
694
  className: 'datawrapper_ad'
634
695
  });
635
696
 
@@ -640,8 +701,11 @@ editor.contentElementTypes.register('dataWrapperChart', {
640
701
  pictogram: img$7,
641
702
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
642
703
  supportedWidthRange: ['xxs', 'full'],
643
- configurationEditor: function configurationEditor(_ref) {
644
- var entry = _ref.entry;
704
+ supportedCaptions: true,
705
+ supportedStyles: ['boxShadow', 'outline'],
706
+ configurationEditor({
707
+ entry
708
+ }) {
645
709
  this.tab('general', function () {
646
710
  this.input('url', UrlInputView, {
647
711
  supportedHosts: ['cf.datawrapper.de', 'charts.datawrapper.de', 'datawrapper.dwcdn.de', 'datawrapper.dwcdn.net'],
@@ -657,11 +721,11 @@ editor.contentElementTypes.register('dataWrapperChart', {
657
721
  defaultValue: '#323d4d'
658
722
  });
659
723
  this.group('ContentElementPosition', {
660
- entry: entry
724
+ entry
661
725
  });
662
726
  this.view(SeparatorView);
663
727
  this.group('ContentElementCaption', {
664
- entry: entry
728
+ entry
665
729
  });
666
730
  });
667
731
  }
@@ -674,8 +738,11 @@ editor.contentElementTypes.register('inlineBeforeAfter', {
674
738
  category: 'interactive',
675
739
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right', 'backdrop'],
676
740
  supportedWidthRange: ['xxs', 'full'],
677
- configurationEditor: function configurationEditor(_ref) {
678
- var entry = _ref.entry;
741
+ supportedCaptions: true,
742
+ supportedStyles: ['boxShadow', 'outline'],
743
+ configurationEditor({
744
+ entry
745
+ }) {
679
746
  this.tab('general', function () {
680
747
  this.input('before_id', FileInputView, {
681
748
  collection: 'image_files',
@@ -694,11 +761,11 @@ editor.contentElementTypes.register('inlineBeforeAfter', {
694
761
  this.input('initial_slider_position', SliderInputView);
695
762
  this.input('slider_color', ColorInputView$1);
696
763
  this.group('ContentElementPosition', {
697
- entry: entry
764
+ entry
698
765
  });
699
766
  this.view(SeparatorView);
700
767
  this.group('ContentElementCaption', {
701
- entry: entry
768
+ entry
702
769
  });
703
770
  this.group('ContentElementInlineFileRightsSettings');
704
771
  });
@@ -708,41 +775,47 @@ editor.contentElementTypes.register('inlineBeforeAfter', {
708
775
  }
709
776
  });
710
777
 
711
- var SidebarRouter = Marionette.AppRouter.extend({
778
+ const SidebarRouter = Marionette.AppRouter.extend({
712
779
  appRoutes: {
713
780
  'scrolled/external_links/:id/:link_id': 'link'
714
781
  }
715
782
  });
716
783
 
717
- var SidebarEditLinkView = Marionette.Layout.extend({
718
- template: function template(data) {
719
- return "\n <a class=\"back\">".concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.back'), "</a>\n <a class=\"destroy\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.destroy'), "</a>\n\n <div class='form_container'></div>\n ");
784
+ const SidebarEditLinkView = EditConfigurationView.extend({
785
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.externalLinkList',
786
+ containingCollection() {
787
+ return this.options.collection;
720
788
  },
721
- className: 'edit_external_link',
722
- regions: {
723
- formContainer: '.form_container'
789
+ getConfigurationModel() {
790
+ return this.model;
724
791
  },
725
- events: {
726
- 'click a.back': 'goBack',
727
- 'click a.destroy': 'destroyLink'
792
+ goBackPath() {
793
+ return `/scrolled/content_elements/${this.options.contentElement.get('id')}`;
728
794
  },
729
- initialize: function initialize(options) {},
730
- onRender: function onRender() {
731
- var configurationEditor = new ConfigurationEditorView({
732
- model: this.model,
733
- attributeTranslationKeyPrefixes: ['pageflow_scrolled.editor.content_elements.externalLinkList.attributes'],
734
- tabTranslationKeyPrefix: 'pageflow_scrolled.editor.content_elements.externalLinkList.tabs'
795
+ goBack() {
796
+ this.options.contentElement.postCommand({
797
+ type: 'SET_SELECTED_ITEM',
798
+ index: -1
735
799
  });
736
- var self = this;
737
- var thumbnailAspectRatio = this.options.contentElement.configuration.get('thumbnailAspectRatio');
738
- var previewAspectRatio = this.options.entry.getAspectRatio(thumbnailAspectRatio);
739
- var thumbnailFit = this.options.contentElement.configuration.get('thumbnailFit');
800
+ EditConfigurationView.prototype.goBack.call(this);
801
+ },
802
+ getActionsMenuItems() {
803
+ return [new DestroyLinkMenuItem({}, {
804
+ collection: this.options.collection,
805
+ model: this.model
806
+ })];
807
+ },
808
+ configure(configurationEditor) {
809
+ const contentElement = this.options.contentElement;
810
+ const thumbnailAspectRatio = contentElement.configuration.get('thumbnailAspectRatio');
811
+ const previewAspectRatio = this.options.entry.getAspectRatio(thumbnailAspectRatio);
812
+ const thumbnailFit = contentElement.configuration.get('thumbnailFit');
740
813
  configurationEditor.tab('edit_link', function () {
741
814
  this.input('thumbnail', FileInputView, {
742
815
  collection: 'image_files',
743
816
  fileSelectionHandler: 'contentElement.externalLinks.link',
744
817
  fileSelectionHandlerOptions: {
745
- contentElementId: self.options.contentElement.get('id')
818
+ contentElementId: contentElement.get('id')
746
819
  },
747
820
  positioning: previewAspectRatio && thumbnailFit !== 'contain',
748
821
  positioningOptions: {
@@ -756,148 +829,129 @@ var SidebarEditLinkView = Marionette.Layout.extend({
756
829
  text: I18n.t('pageflow_scrolled.editor.content_elements.textBlock.help_texts.shortcuts')
757
830
  });
758
831
  });
759
- this.formContainer.show(configurationEditor);
760
- },
761
- goBack: function goBack() {
762
- this.options.contentElement.postCommand({
763
- type: 'SET_SELECTED_ITEM',
764
- index: -1
765
- });
766
- editor$1.navigate("/scrolled/content_elements/".concat(this.options.contentElement.get('id')), {
767
- trigger: true
768
- });
769
- },
770
- destroyLink: function destroyLink() {
771
- if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_item'))) {
772
- this.options.collection.remove(this.model);
773
- this.goBack();
774
- }
832
+ }
833
+ });
834
+ const DestroyLinkMenuItem = DestroyMenuItem.extend({
835
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.externalLinkList',
836
+ destroyModel() {
837
+ this.options.collection.remove(this.options.model);
775
838
  }
776
839
  });
777
840
 
778
- function _arrayWithoutHoles(arr) {
779
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
780
- }
781
-
782
- function _iterableToArray(iter) {
783
- if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
784
- }
785
-
786
- function _nonIterableSpread() {
787
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
788
- }
789
-
790
- function _toConsumableArray(arr) {
791
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
792
- }
793
-
794
- var ExternalLinkModel = Backbone.Model.extend({
841
+ const ExternalLinkModel = Backbone.Model.extend({
795
842
  modelName: 'ExternalLink',
796
843
  i18nKey: 'external_link',
797
844
  mixins: [transientReferences],
798
- thumbnailUrl: function thumbnailUrl() {
845
+ thumbnailFile: function () {
799
846
  var _this$thumbnail;
800
- return ((_this$thumbnail = this.thumbnail()) === null || _this$thumbnail === void 0 ? void 0 : _this$thumbnail.get('thumbnail_url')) || '';
847
+ return (_this$thumbnail = this.thumbnail()) === null || _this$thumbnail === void 0 ? void 0 : _this$thumbnail.thumbnailFile();
801
848
  },
802
- thumbnail: function thumbnail() {
849
+ thumbnail: function () {
803
850
  return this.collection.entry.getFileCollection('image_files').getByPermaId(this.get('thumbnail'));
804
851
  },
805
- title: function title() {
806
- var configuration = this.collection.contentElement.configuration;
852
+ title: function () {
853
+ const configuration = this.collection.contentElement.configuration;
807
854
  if (configuration.get('textPosition') === 'none') {
808
855
  var _this$thumbnail2;
809
856
  return (_this$thumbnail2 = this.thumbnail()) === null || _this$thumbnail2 === void 0 ? void 0 : _this$thumbnail2.configuration.get('alt');
810
857
  } else {
811
858
  var _itemTexts$this$id, _itemTexts$this$id2, _itemTexts$this$id2$t, _itemTexts$this$id2$t2, _itemTexts$this$id2$t3;
812
- var itemTexts = configuration.get('itemTexts');
859
+ const itemTexts = configuration.get('itemTexts');
813
860
  return (itemTexts === null || itemTexts === void 0 ? void 0 : (_itemTexts$this$id = itemTexts[this.id]) === null || _itemTexts$this$id === void 0 ? void 0 : _itemTexts$this$id.title) ? itemTexts === null || itemTexts === void 0 ? void 0 : (_itemTexts$this$id2 = itemTexts[this.id]) === null || _itemTexts$this$id2 === void 0 ? void 0 : (_itemTexts$this$id2$t = _itemTexts$this$id2.title[0]) === null || _itemTexts$this$id2$t === void 0 ? void 0 : (_itemTexts$this$id2$t2 = _itemTexts$this$id2$t.children) === null || _itemTexts$this$id2$t2 === void 0 ? void 0 : (_itemTexts$this$id2$t3 = _itemTexts$this$id2$t2[0]) === null || _itemTexts$this$id2$t3 === void 0 ? void 0 : _itemTexts$this$id2$t3.text : this.get('title');
814
861
  }
815
862
  },
816
- getFilePosition: function getFilePosition(attribute, coord) {
817
- var cropPosition = this.get('thumbnailCropPosition');
863
+ getFilePosition: function (attribute, coord) {
864
+ const cropPosition = this.get('thumbnailCropPosition');
818
865
  return cropPosition ? cropPosition[coord] : 50;
819
866
  },
820
- setFilePosition: function setFilePosition(attribute, coord, value) {
821
- this.set('thumbnailCropPosition', _objectSpread2(_objectSpread2({}, this.get('thumbnailCropPosition')), {}, _defineProperty({}, coord, value)));
867
+ setFilePosition: function (attribute, coord, value) {
868
+ this.set('thumbnailCropPosition', {
869
+ ...this.get('thumbnailCropPosition'),
870
+ [coord]: value
871
+ });
822
872
  },
823
- setFilePositions: function setFilePositions(attribute, x, y) {
873
+ setFilePositions: function (attribute, x, y) {
824
874
  this.set('thumbnailCropPosition', {
825
- x: x,
826
- y: y
875
+ x,
876
+ y
827
877
  });
828
878
  },
829
- highlight: function highlight() {
879
+ highlight() {
830
880
  this.collection.contentElement.postCommand({
831
881
  type: 'HIGHLIGHT_ITEM',
832
882
  index: this.collection.indexOf(this)
833
883
  });
834
884
  },
835
- resetHighlight: function resetHighlight() {
885
+ resetHighlight() {
836
886
  this.collection.contentElement.postCommand({
837
887
  type: 'RESET_ITEM_HIGHLIGHT'
838
888
  });
839
889
  }
840
890
  });
841
891
 
842
- var ExternalLinkCollection = Backbone.Collection.extend({
892
+ const ExternalLinkCollection = Backbone.Collection.extend({
843
893
  model: ExternalLinkModel,
844
894
  comparator: 'position',
845
- initialize: function initialize(models, options) {
846
- var _this = this;
895
+ initialize: function (models, options) {
847
896
  this.entry = options.entry;
848
897
  this.contentElement = options.contentElement;
849
898
  this.listenTo(this, 'add sort change', this.updateConfiguration);
850
- this.listenTo(this, 'remove', function () {
851
- return _this.updateConfiguration({
852
- prune: true
853
- });
854
- });
899
+ this.listenTo(this, 'remove', () => this.updateConfiguration({
900
+ prune: true
901
+ }));
855
902
  },
856
- modelId: function modelId(attrs) {
903
+ modelId: function (attrs) {
857
904
  return attrs.id;
858
905
  },
859
- updateConfiguration: function updateConfiguration(_ref) {
860
- var prune = _ref.prune;
861
- var updatedAttributes = {
906
+ updateConfiguration: function ({
907
+ prune
908
+ }) {
909
+ let updatedAttributes = {
862
910
  links: this.toJSON()
863
911
  };
864
912
  if (prune) {
865
- updatedAttributes = _objectSpread2(_objectSpread2(_objectSpread2({}, updatedAttributes), this.getPrunedProperty('itemTexts')), this.getPrunedProperty('itemLinks'));
913
+ updatedAttributes = {
914
+ ...updatedAttributes,
915
+ ...this.getPrunedProperty('itemTexts'),
916
+ ...this.getPrunedProperty('itemLinks')
917
+ };
866
918
  }
867
919
  this.contentElement.configuration.set(updatedAttributes);
868
920
  },
869
- getPrunedProperty: function getPrunedProperty(propertyName) {
870
- return _defineProperty({}, propertyName, _.pick.apply(_, [this.contentElement.configuration.get(propertyName) || {}].concat(_toConsumableArray(this.pluck('id')))));
921
+ getPrunedProperty(propertyName) {
922
+ return {
923
+ [propertyName]: _.pick(this.contentElement.configuration.get(propertyName) || {}, ...this.pluck('id'))
924
+ };
871
925
  },
872
- addNewLink: function addNewLink() {
873
- var id = this.length ? Math.max.apply(Math, _toConsumableArray(this.pluck('id'))) + 1 : 1;
926
+ addNewLink() {
927
+ const id = this.length ? Math.max(...this.pluck('id')) + 1 : 1;
874
928
  this.add({
875
- id: id
929
+ id
876
930
  });
877
931
  return this.get(id);
878
932
  },
879
- saveOrder: function saveOrder() {}
933
+ saveOrder() {}
880
934
  });
881
935
  ExternalLinkCollection.forContentElement = function (contentElement, entry) {
882
936
  return new ExternalLinkCollection(contentElement.configuration.get('links') || [], {
883
- entry: entry,
884
- contentElement: contentElement
937
+ entry,
938
+ contentElement
885
939
  });
886
940
  };
887
941
 
888
- var SidebarController = Marionette.Controller.extend({
889
- initialize: function initialize(options) {
942
+ const SidebarController = Marionette.Controller.extend({
943
+ initialize: function (options) {
890
944
  this.entry = options.entry;
891
945
  this.region = options.region;
892
946
  },
893
- link: function link(id, linkId) {
894
- var contentElement = this.entry.contentElements.get(id);
895
- var linksCollection = ExternalLinkCollection.forContentElement(contentElement, this.entry);
947
+ link: function (id, linkId) {
948
+ const contentElement = this.entry.contentElements.get(id);
949
+ const linksCollection = ExternalLinkCollection.forContentElement(contentElement, this.entry);
896
950
  this.region.show(new SidebarEditLinkView({
897
951
  model: linksCollection.get(linkId),
898
952
  collection: linksCollection,
899
953
  entry: this.entry,
900
- contentElement: contentElement
954
+ contentElement
901
955
  }));
902
956
  }
903
957
  });
@@ -933,19 +987,23 @@ var css = ".SidebarListView-module_linksContainer__HvWq- {\n}\n";
933
987
  var styles = {"linksContainer":"SidebarListView-module_linksContainer__HvWq-"};
934
988
  styleInject(css);
935
989
 
936
- var SidebarListView = Marionette.Layout.extend({
937
- template: function template(data) {
938
- return "\n <label>".concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.items'), "</label>\n <div class='").concat(styles.linksContainer, "'></div>\n <button class=\"").concat(buttonStyles.addButton, "\">\n ").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.add'), "\n </button>\n ");
939
- },
990
+ const SidebarListView = Marionette.Layout.extend({
991
+ template: data => `
992
+ <label>${I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.items')}</label>
993
+ <div class='${styles.linksContainer}'></div>
994
+ <button class="${buttonStyles.addButton}">
995
+ ${I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.add')}
996
+ </button>
997
+ `,
940
998
  regions: cssModulesUtils.ui(styles, 'linksContainer'),
941
999
  events: cssModulesUtils.events(buttonStyles, {
942
1000
  'click addButton': 'addElement'
943
1001
  }),
944
- onRender: function onRender() {
1002
+ onRender: function () {
945
1003
  this.listenTo(this.options.contentElement.configuration, 'change:textPosition', this.renderListView);
946
1004
  this.renderListView();
947
1005
  },
948
- renderListView: function renderListView() {
1006
+ renderListView() {
949
1007
  this.linksContainer.show(new ListView({
950
1008
  collection: this.collection,
951
1009
  sortable: true,
@@ -954,26 +1012,26 @@ var SidebarListView = Marionette.Layout.extend({
954
1012
  onRemove: _.bind(this.onRemove, this)
955
1013
  }));
956
1014
  },
957
- addElement: function addElement() {
1015
+ addElement: function () {
958
1016
  this.collection.addNewLink();
959
1017
  },
960
- onEdit: function onEdit(linkModel) {
1018
+ onEdit: function (linkModel) {
961
1019
  this.options.contentElement.postCommand({
962
1020
  type: 'SET_SELECTED_ITEM',
963
1021
  index: this.collection.indexOf(linkModel)
964
1022
  });
965
- editor.navigate("/scrolled/external_links/".concat(this.options.contentElement.id, "/").concat(linkModel.id), {
1023
+ editor.navigate(`/scrolled/external_links/${this.options.contentElement.id}/${linkModel.id}`, {
966
1024
  trigger: true
967
1025
  });
968
1026
  },
969
- onRemove: function onRemove(linkModel) {
1027
+ onRemove: function (linkModel) {
970
1028
  if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_item'))) {
971
1029
  this.collection.remove(linkModel);
972
1030
  }
973
1031
  }
974
1032
  });
975
1033
 
976
- var linkWidths = {
1034
+ const linkWidths = {
977
1035
  xs: -2,
978
1036
  sm: -1,
979
1037
  md: 0,
@@ -981,21 +1039,43 @@ var linkWidths = {
981
1039
  xl: 2,
982
1040
  xxl: 3
983
1041
  };
984
- function maxLinkWidth(_ref) {
985
- var layout = _ref.layout,
986
- textPosition = _ref.textPosition,
987
- width = _ref.width;
1042
+ function maxLinkWidth({
1043
+ layout,
1044
+ textPosition,
1045
+ width
1046
+ }) {
1047
+ width = width || contentElementWidths.md;
988
1048
  if (layout === 'center' || layout === 'centerRagged') {
989
1049
  if (textPosition === 'right') {
990
- return _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, contentElementWidths.md, linkWidths.md), contentElementWidths.lg, linkWidths.lg), contentElementWidths.xl, linkWidths.xl), contentElementWidths.full, linkWidths.xl)[width];
1050
+ return {
1051
+ [contentElementWidths.md]: linkWidths.md,
1052
+ [contentElementWidths.lg]: linkWidths.lg,
1053
+ [contentElementWidths.xl]: linkWidths.xl,
1054
+ [contentElementWidths.full]: linkWidths.xl
1055
+ }[width];
991
1056
  } else {
992
- return _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, contentElementWidths.md, linkWidths.lg), contentElementWidths.lg, linkWidths.xl), contentElementWidths.xl, linkWidths.xxl), contentElementWidths.full, linkWidths.xxl)[width];
1057
+ return {
1058
+ [contentElementWidths.md]: linkWidths.lg,
1059
+ [contentElementWidths.lg]: linkWidths.xl,
1060
+ [contentElementWidths.xl]: linkWidths.xxl,
1061
+ [contentElementWidths.full]: linkWidths.xxl
1062
+ }[width];
993
1063
  }
994
1064
  } else {
995
1065
  if (textPosition === 'right') {
996
- return _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, contentElementWidths.md, linkWidths.sm), contentElementWidths.lg, linkWidths.md), contentElementWidths.xl, linkWidths.xl), contentElementWidths.full, linkWidths.xl)[width];
1066
+ return {
1067
+ [contentElementWidths.md]: linkWidths.sm,
1068
+ [contentElementWidths.lg]: linkWidths.md,
1069
+ [contentElementWidths.xl]: linkWidths.xl,
1070
+ [contentElementWidths.full]: linkWidths.xl
1071
+ }[width];
997
1072
  } else {
998
- return _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, contentElementWidths.md, linkWidths.lg), contentElementWidths.lg, linkWidths.lg), contentElementWidths.xl, linkWidths.xxl), contentElementWidths.full, linkWidths.xxl)[width];
1073
+ return {
1074
+ [contentElementWidths.md]: linkWidths.lg,
1075
+ [contentElementWidths.lg]: linkWidths.lg,
1076
+ [contentElementWidths.xl]: linkWidths.xxl,
1077
+ [contentElementWidths.full]: linkWidths.xxl
1078
+ }[width];
999
1079
  }
1000
1080
  }
1001
1081
  }
@@ -1015,20 +1095,44 @@ editor.contentElementTypes.register('externalLinkList', {
1015
1095
  category: 'tilesAndLinks',
1016
1096
  supportedPositions: ['inline', 'standAlone'],
1017
1097
  supportedWidthRange: ['m', 'full'],
1098
+ supportedStyles: ['boxShadow', 'outline'],
1018
1099
  defaultConfig: {
1019
1100
  thumbnailAspectRatio: 'square'
1020
1101
  },
1021
- editorPath: function editorPath(contentElement) {
1022
- var selectedItemId = contentElement.transientState.get('selectedItemId');
1102
+ editorPath(contentElement) {
1103
+ const selectedItemId = contentElement.transientState.get('selectedItemId');
1023
1104
  if (selectedItemId) {
1024
- return "/scrolled/external_links/".concat(contentElement.id, "/").concat(selectedItemId);
1105
+ return `/scrolled/external_links/${contentElement.id}/${selectedItemId}`;
1106
+ }
1107
+ },
1108
+ configurationPlace(contentElement, path) {
1109
+ const [propertyName, index, linkProperty] = path;
1110
+ if (propertyName !== 'links') {
1111
+ return;
1025
1112
  }
1113
+ const link = contentElement.configuration.get('links')[index];
1114
+ return {
1115
+ label: attributeLabel(linkProperty),
1116
+ select() {
1117
+ contentElement.postCommand({
1118
+ type: 'SET_SELECTED_ITEM',
1119
+ index: Number(index)
1120
+ });
1121
+ contentElement.select({
1122
+ navigate: false
1123
+ });
1124
+ editor.navigate(`/scrolled/external_links/${contentElement.id}/${link.id}`, {
1125
+ trigger: true
1126
+ });
1127
+ }
1128
+ };
1026
1129
  },
1027
- configurationEditor: function configurationEditor(_ref) {
1028
- var entry = _ref.entry,
1029
- contentElement = _ref.contentElement;
1130
+ configurationEditor({
1131
+ entry,
1132
+ contentElement
1133
+ }) {
1030
1134
  this.tab('general', function () {
1031
- var layout = contentElement.section.configuration.get('layout');
1135
+ const layout = contentElement.section.configuration.get('layout');
1032
1136
  this.view(SidebarListView, {
1033
1137
  contentElement: this.model.parent,
1034
1138
  collection: ExternalLinkCollection.forContentElement(this.model.parent, entry)
@@ -1037,7 +1141,7 @@ editor.contentElementTypes.register('externalLinkList', {
1037
1141
  values: ['below', 'right', 'overlay', 'none']
1038
1142
  });
1039
1143
  this.group('ContentElementVariant', {
1040
- entry: entry
1144
+ entry
1041
1145
  });
1042
1146
  this.input('overlayOpacity', SliderInputView, {
1043
1147
  defaultValue: 70,
@@ -1046,63 +1150,43 @@ editor.contentElementTypes.register('externalLinkList', {
1046
1150
  });
1047
1151
  this.view(SeparatorView);
1048
1152
  this.group('ContentElementPosition', {
1049
- entry: entry
1153
+ entry
1050
1154
  });
1051
1155
  this.view(SeparatorView);
1052
1156
  this.input('enableScroller', SelectInputView, {
1053
1157
  values: ['never', 'always']
1054
1158
  });
1055
1159
  this.input('linkWidth', SliderInputView, {
1056
- displayText: function displayText(value) {
1057
- return ['XS', 'S', 'M', 'L', 'XL', 'XXL'][value + 2];
1058
- },
1160
+ displayText: value => ['XS', 'S', 'M', 'L', 'XL', 'XXL'][value + 2],
1059
1161
  saveOnSlide: true,
1060
1162
  minValue: -2,
1061
1163
  maxValueBinding: ['width', 'textPosition'],
1062
- maxValue: function maxValue(_ref2) {
1063
- var _ref3 = _slicedToArray(_ref2, 2),
1064
- width = _ref3[0],
1065
- textPosition = _ref3[1];
1066
- return maxLinkWidth({
1067
- width: width,
1068
- layout: layout,
1069
- textPosition: textPosition
1070
- });
1071
- },
1164
+ maxValue: ([width, textPosition]) => maxLinkWidth({
1165
+ width,
1166
+ layout,
1167
+ textPosition
1168
+ }),
1072
1169
  defaultValue: -1
1073
1170
  });
1074
1171
  this.input('linkAlignment', SelectInputView, {
1075
1172
  values: ['spaceEvenly', 'left', 'right', 'center'],
1076
1173
  visibleBinding: ['textPosition', 'enableScroller'],
1077
- visible: function visible(_ref4) {
1078
- var _ref5 = _slicedToArray(_ref4, 2),
1079
- textPosition = _ref5[0],
1080
- enableScroller = _ref5[1];
1081
- return textPosition !== 'right' && enableScroller !== 'always';
1082
- }
1174
+ visible: ([textPosition, enableScroller]) => textPosition !== 'right' && enableScroller !== 'always'
1083
1175
  });
1084
1176
  this.input('linkAlignment', SelectInputView, {
1085
1177
  values: ['left'],
1086
1178
  disabled: true,
1087
1179
  visibleBinding: ['textPosition', 'enableScroller'],
1088
- visible: function visible(_ref6) {
1089
- var _ref7 = _slicedToArray(_ref6, 2),
1090
- textPosition = _ref7[0],
1091
- enableScroller = _ref7[1];
1092
- return textPosition !== 'right' && enableScroller === 'always';
1093
- }
1180
+ visible: ([textPosition, enableScroller]) => textPosition !== 'right' && enableScroller === 'always'
1094
1181
  });
1095
1182
  this.input('thumbnailSize', SelectInputView, {
1096
1183
  values: ['small', 'medium', 'large'],
1097
1184
  visibleBinding: 'textPosition',
1098
1185
  visibleBindingValue: 'right'
1099
1186
  });
1100
- var _entry$getAspectRatio = entry.getAspectRatios({
1101
- includeOriginal: true
1102
- }),
1103
- _entry$getAspectRatio2 = _slicedToArray(_entry$getAspectRatio, 2),
1104
- aspectRatios = _entry$getAspectRatio2[0],
1105
- aspectRatiosTexts = _entry$getAspectRatio2[1];
1187
+ const [aspectRatios, aspectRatiosTexts] = entry.getAspectRatios({
1188
+ includeOriginal: true
1189
+ });
1106
1190
  this.input('thumbnailAspectRatio', SelectInputView, {
1107
1191
  values: aspectRatios,
1108
1192
  texts: aspectRatiosTexts
@@ -1116,7 +1200,16 @@ editor.contentElementTypes.register('externalLinkList', {
1116
1200
  this.input('textAlign', SelectInputView, {
1117
1201
  values: ['left', 'right', 'center']
1118
1202
  });
1119
- this.input('displayButtons', CheckBoxInputView);
1203
+ this.input('backfaces', CheckBoxInputView);
1204
+ this.input('displayButtons', CheckBoxInputView, {
1205
+ disabledBinding: 'backfaces',
1206
+ displayCheckedIfDisabled: true
1207
+ });
1208
+ this.group('LinkButtonVariant', {
1209
+ entry,
1210
+ visibleBinding: ['displayButtons', 'backfaces'],
1211
+ visible: ([displayButtons, backfaces]) => displayButtons || backfaces
1212
+ });
1120
1213
  this.group('ContentElementInlineFileRightsSettings');
1121
1214
  });
1122
1215
  }
@@ -1124,31 +1217,36 @@ editor.contentElementTypes.register('externalLinkList', {
1124
1217
 
1125
1218
  // register file handler for thumbnail of external link
1126
1219
  editor.registerFileSelectionHandler('contentElement.externalLinks.link', function (options) {
1127
- var contentElement = options.entry.contentElements.get(options.contentElementId);
1128
- var links = ExternalLinkCollection.forContentElement(contentElement, options.entry);
1220
+ const contentElement = options.entry.contentElements.get(options.contentElementId);
1221
+ const links = ExternalLinkCollection.forContentElement(contentElement, options.entry);
1129
1222
  this.call = function (file) {
1130
- var link = links.get(options.id);
1223
+ const link = links.get(options.id);
1131
1224
  link.setReference('thumbnail', file);
1132
1225
  };
1133
1226
  this.getReferer = function () {
1134
1227
  return '/scrolled/external_links/' + contentElement.id + '/' + options.id;
1135
1228
  };
1136
1229
  });
1230
+ function attributeLabel(propertyName) {
1231
+ return I18n.t(`${propertyName}.label`, {
1232
+ scope: 'pageflow_scrolled.editor.content_elements.externalLinkList.attributes'
1233
+ });
1234
+ }
1137
1235
 
1138
- var SET_MODE = 'SET_MODE';
1139
- var DRAG = 'DRAG';
1140
- var CLICK_HANDLE = 'CLICK_HANDLE';
1141
- var DRAG_HANDLE = 'DRAG_HANDLE';
1142
- var DRAG_HANDLE_STOP = 'DRAG_HANDLE_STOP';
1143
- var DOUBLE_CLICK_HANDLE = 'DOUBLE_CLICK_HANDLE';
1144
- var MOUSE_MOVE = 'MOUSE_MOVE';
1145
- var DRAG_POTENTIAL_POINT = 'DRAG_POTENTIAL_POINT';
1146
- var DRAG_POTENTIAL_POINT_STOP = 'DRAG_POTENTIAL_POINT_STOP';
1147
- var CLICK_INDICATOR = 'CLICK_INDICATOR';
1148
- var DRAG_INDICATOR = 'DRAG_INDICATOR';
1149
- var CENTER_INDICATOR = 'CENTER_INDICATOR';
1150
- var UPDATE_SELECTION_POSITION = 'UPDATE_SELECTION_POSITION';
1151
- var BLUR_SELECTION_POSITION = 'BLUR_SELECTION_POSITION';
1236
+ const SET_MODE = 'SET_MODE';
1237
+ const DRAG = 'DRAG';
1238
+ const CLICK_HANDLE = 'CLICK_HANDLE';
1239
+ const DRAG_HANDLE = 'DRAG_HANDLE';
1240
+ const DRAG_HANDLE_STOP = 'DRAG_HANDLE_STOP';
1241
+ const DOUBLE_CLICK_HANDLE = 'DOUBLE_CLICK_HANDLE';
1242
+ const MOUSE_MOVE = 'MOUSE_MOVE';
1243
+ const DRAG_POTENTIAL_POINT = 'DRAG_POTENTIAL_POINT';
1244
+ const DRAG_POTENTIAL_POINT_STOP = 'DRAG_POTENTIAL_POINT_STOP';
1245
+ const CLICK_INDICATOR = 'CLICK_INDICATOR';
1246
+ const DRAG_INDICATOR = 'DRAG_INDICATOR';
1247
+ const CENTER_INDICATOR = 'CENTER_INDICATOR';
1248
+ const UPDATE_SELECTION_POSITION = 'UPDATE_SELECTION_POSITION';
1249
+ const BLUR_SELECTION_POSITION = 'BLUR_SELECTION_POSITION';
1152
1250
  function reducer(state, action) {
1153
1251
  var _state$selection, _state$selection2, _state$selection3;
1154
1252
  switch (action.type) {
@@ -1156,24 +1254,24 @@ function reducer(state, action) {
1156
1254
  if (action.value === state.mode) {
1157
1255
  return state;
1158
1256
  } else if (action.value === 'rect') {
1159
- return _objectSpread2(_objectSpread2({}, state), {}, {
1257
+ return {
1258
+ ...state,
1160
1259
  mode: 'rect',
1161
1260
  previousPolygonPoints: state.points,
1162
1261
  points: getBoundingBox(state.points),
1163
1262
  selection: null
1164
- });
1263
+ };
1165
1264
  } else {
1166
- return _objectSpread2(_objectSpread2({}, state), {}, {
1265
+ return {
1266
+ ...state,
1167
1267
  mode: 'polygon',
1168
1268
  points: state.previousPolygonPoints || state.points,
1169
1269
  selection: null
1170
- });
1270
+ };
1171
1271
  }
1172
1272
  case DRAG:
1173
- var _action$delta = _slicedToArray(action.delta, 2),
1174
- deltaX = _action$delta[0],
1175
- deltaY = _action$delta[1];
1176
- state.points.forEach(function (point) {
1273
+ let [deltaX, deltaY] = action.delta;
1274
+ state.points.forEach(point => {
1177
1275
  if (point[0] + deltaX > 100) {
1178
1276
  deltaX = 100 - point[0];
1179
1277
  }
@@ -1187,70 +1285,74 @@ function reducer(state, action) {
1187
1285
  deltaY = -point[1];
1188
1286
  }
1189
1287
  });
1190
- return _objectSpread2(_objectSpread2({}, state), {}, {
1191
- points: state.points.map(function (point) {
1192
- return [point[0] + deltaX, point[1] + deltaY];
1193
- }),
1288
+ return {
1289
+ ...state,
1290
+ points: state.points.map(point => [point[0] + deltaX, point[1] + deltaY]),
1194
1291
  indicatorPosition: [state.indicatorPosition[0] + deltaX, state.indicatorPosition[1] + deltaY]
1195
- });
1292
+ };
1196
1293
  case CLICK_HANDLE:
1197
1294
  if (state.mode === 'polygon') {
1198
- return _objectSpread2(_objectSpread2({}, state), {}, {
1295
+ return {
1296
+ ...state,
1199
1297
  selection: {
1200
1298
  type: 'handle',
1201
1299
  index: action.index,
1202
1300
  position: round(state.points[action.index])
1203
1301
  }
1204
- });
1302
+ };
1205
1303
  } else {
1206
- return _objectSpread2(_objectSpread2({}, state), {}, {
1304
+ return {
1305
+ ...state,
1207
1306
  selection: rectHandleSelection(action.index, state.points)
1208
- });
1307
+ };
1209
1308
  }
1210
1309
  case DRAG_HANDLE:
1211
1310
  state = updatePoints(state, action.index, action.cursor);
1212
- return _objectSpread2(_objectSpread2({}, state), {}, {
1311
+ return {
1312
+ ...state,
1213
1313
  indicatorPosition: ensureInPolygon(state.points, state.indicatorPosition)
1214
- });
1314
+ };
1215
1315
  case DRAG_HANDLE_STOP:
1216
- return _objectSpread2(_objectSpread2({}, state), {}, {
1316
+ return {
1317
+ ...state,
1217
1318
  startPoints: null
1218
- });
1319
+ };
1219
1320
  case DOUBLE_CLICK_HANDLE:
1220
1321
  if (state.mode !== 'polygon' || state.points.length <= 3) {
1221
1322
  return state;
1222
1323
  }
1223
- var points = [].concat(_toConsumableArray(state.points.slice(0, action.index)), _toConsumableArray(state.points.slice(action.index + 1)));
1224
- return _objectSpread2(_objectSpread2({}, state), {}, {
1225
- points: points,
1324
+ const points = [...state.points.slice(0, action.index), ...state.points.slice(action.index + 1)];
1325
+ return {
1326
+ ...state,
1327
+ points,
1226
1328
  potentialPoint: null,
1227
1329
  indicatorPosition: ensureInPolygon(points, state.indicatorPosition),
1228
1330
  selection: null
1229
- });
1331
+ };
1230
1332
  case MOUSE_MOVE:
1231
1333
  if (state.mode !== 'polygon' || state.draggingPotentialPoint) {
1232
1334
  return state;
1233
1335
  }
1234
- var _closestPointOnPolygo = closestPointOnPolygon(state.points, action.cursor),
1235
- _closestPointOnPolygo2 = _slicedToArray(_closestPointOnPolygo, 2),
1236
- index = _closestPointOnPolygo2[0],
1237
- potentialPoint = _closestPointOnPolygo2[1];
1238
- return _objectSpread2(_objectSpread2({}, state), {}, {
1336
+ const [index, potentialPoint] = closestPointOnPolygon(state.points, action.cursor);
1337
+ return {
1338
+ ...state,
1239
1339
  potentialPointInsertIndex: index,
1240
- potentialPoint: potentialPoint
1241
- });
1340
+ potentialPoint
1341
+ };
1242
1342
  case DRAG_POTENTIAL_POINT:
1243
- return _objectSpread2(_objectSpread2({}, state), {}, {
1343
+ return {
1344
+ ...state,
1244
1345
  draggingPotentialPoint: true,
1245
1346
  potentialPoint: action.cursor,
1246
1347
  selection: {
1247
1348
  type: 'potentialPoint',
1248
1349
  position: round(action.cursor)
1249
1350
  }
1250
- });
1351
+ };
1251
1352
  case DRAG_POTENTIAL_POINT_STOP:
1252
- var newPoints = withPotentialPoint(state);
1253
- return _objectSpread2(_objectSpread2({}, state), {}, {
1353
+ const newPoints = withPotentialPoint(state);
1354
+ return {
1355
+ ...state,
1254
1356
  points: newPoints,
1255
1357
  draggingPotentialPoint: false,
1256
1358
  potentialPoint: null,
@@ -1259,35 +1361,40 @@ function reducer(state, action) {
1259
1361
  index: state.potentialPointInsertIndex,
1260
1362
  position: round(newPoints[state.potentialPointInsertIndex])
1261
1363
  }
1262
- });
1364
+ };
1263
1365
  case CLICK_INDICATOR:
1264
- return _objectSpread2(_objectSpread2({}, state), {}, {
1366
+ return {
1367
+ ...state,
1265
1368
  selection: {
1266
1369
  type: 'indicator',
1267
1370
  position: round(state.indicatorPosition)
1268
1371
  }
1269
- });
1372
+ };
1270
1373
  case DRAG_INDICATOR:
1271
- var indicatorPosition = ensureInPolygon(state.points, action.cursor);
1272
- return _objectSpread2(_objectSpread2({}, state), {}, {
1273
- indicatorPosition: indicatorPosition,
1374
+ const indicatorPosition = ensureInPolygon(state.points, action.cursor);
1375
+ return {
1376
+ ...state,
1377
+ indicatorPosition,
1274
1378
  selection: {
1275
1379
  type: 'indicator',
1276
1380
  position: round(indicatorPosition)
1277
1381
  }
1278
- });
1382
+ };
1279
1383
  case CENTER_INDICATOR:
1280
- return _objectSpread2(_objectSpread2({}, state), {}, {
1384
+ return {
1385
+ ...state,
1281
1386
  indicatorPosition: polygonCentroid(state.points)
1282
- });
1387
+ };
1283
1388
  case UPDATE_SELECTION_POSITION:
1284
1389
  if (((_state$selection = state.selection) === null || _state$selection === void 0 ? void 0 : _state$selection.type) === 'indicator') {
1285
- return _objectSpread2(_objectSpread2({}, state), {}, {
1390
+ return {
1391
+ ...state,
1286
1392
  indicatorPosition: ensureInPolygon(state.points, action.position),
1287
- selection: _objectSpread2(_objectSpread2({}, state.selection), {}, {
1393
+ selection: {
1394
+ ...state.selection,
1288
1395
  position: action.position
1289
- })
1290
- });
1396
+ }
1397
+ };
1291
1398
  } else if (((_state$selection2 = state.selection) === null || _state$selection2 === void 0 ? void 0 : _state$selection2.type) === 'handle') {
1292
1399
  return updatePoints(state, state.selection.index, ensureInBounds(action.position), action.position);
1293
1400
  } else {
@@ -1295,24 +1402,28 @@ function reducer(state, action) {
1295
1402
  }
1296
1403
  case BLUR_SELECTION_POSITION:
1297
1404
  if (((_state$selection3 = state.selection) === null || _state$selection3 === void 0 ? void 0 : _state$selection3.type) === 'indicator') {
1298
- return _objectSpread2(_objectSpread2({}, state), {}, {
1299
- selection: _objectSpread2(_objectSpread2({}, state.selection), {}, {
1405
+ return {
1406
+ ...state,
1407
+ selection: {
1408
+ ...state.selection,
1300
1409
  position: state.indicatorPosition
1301
- })
1302
- });
1410
+ }
1411
+ };
1303
1412
  } else if (state.selection) {
1304
- return _objectSpread2(_objectSpread2({}, state), {}, {
1413
+ return {
1414
+ ...state,
1305
1415
  startPoints: null,
1306
- selection: _objectSpread2(_objectSpread2({}, state.selection), {}, {
1416
+ selection: {
1417
+ ...state.selection,
1307
1418
  position: handles(state)[state.selection.index].point
1308
- }),
1419
+ },
1309
1420
  indicatorPosition: ensureInPolygon(state.points, state.indicatorPosition)
1310
- });
1421
+ };
1311
1422
  } else {
1312
1423
  return state;
1313
1424
  }
1314
1425
  default:
1315
- throw new Error("Unknown action ".concat(action.type, "."));
1426
+ throw new Error(`Unknown action ${action.type}.`);
1316
1427
  }
1317
1428
  }
1318
1429
  function drawnOutlinePoints(state) {
@@ -1322,50 +1433,46 @@ function drawnOutlinePoints(state) {
1322
1433
  return state.points;
1323
1434
  }
1324
1435
  }
1325
- var rectCursors = ['nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize'];
1436
+ const rectCursors = ['nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize'];
1326
1437
  function handles(state) {
1327
1438
  if (state.mode === 'rect') {
1328
- return state.points.flatMap(function (point, index) {
1329
- return [point, midpoint(point, state.points[(index + 1) % state.points.length])];
1330
- }).map(function (point, index) {
1331
- return {
1332
- point: point,
1333
- axis: index % 4 === 1 ? 'y' : index % 4 === 3 ? 'x' : null,
1334
- cursor: rectCursors[index % 4],
1335
- deletable: false
1336
- };
1337
- });
1439
+ return state.points.flatMap((point, index) => [point, midpoint(point, state.points[(index + 1) % state.points.length])]).map((point, index) => ({
1440
+ point,
1441
+ axis: index % 4 === 1 ? 'y' : index % 4 === 3 ? 'x' : null,
1442
+ cursor: rectCursors[index % 4],
1443
+ deletable: false
1444
+ }));
1338
1445
  } else {
1339
- return state.points.map(function (point) {
1340
- return {
1341
- point: point,
1342
- circle: true,
1343
- cursor: 'move',
1344
- deletable: state.points.length > 3
1345
- };
1346
- });
1446
+ return state.points.map(point => ({
1447
+ point,
1448
+ circle: true,
1449
+ cursor: 'move',
1450
+ deletable: state.points.length > 3
1451
+ }));
1347
1452
  }
1348
1453
  }
1349
1454
  function updatePoints(state, index, position, selectionPosition) {
1350
1455
  if (state.mode === 'polygon') {
1351
- return _objectSpread2(_objectSpread2({}, state), {}, {
1352
- points: [].concat(_toConsumableArray(state.points.slice(0, index)), [position], _toConsumableArray(state.points.slice(index + 1))),
1456
+ return {
1457
+ ...state,
1458
+ points: [...state.points.slice(0, index), position, ...state.points.slice(index + 1)],
1353
1459
  selection: {
1354
1460
  type: 'handle',
1355
1461
  index: index,
1356
1462
  position: selectionPosition || round(position)
1357
1463
  }
1358
- });
1464
+ };
1359
1465
  } else {
1360
- var startPoints = state.startPoints || (rectHandleAxis(index) === 'both' ? [state.points[(index / 2 + 2) % 4]] : [state.points[(index + 3) / 2 % 4], state.points[(index + 5) / 2 % 4]]);
1466
+ const startPoints = state.startPoints || (rectHandleAxis(index) === 'both' ? [state.points[(index / 2 + 2) % 4]] : [state.points[(index + 3) / 2 % 4], state.points[(index + 5) / 2 % 4]]);
1361
1467
  position = constrainToAxis(index, position, state.points);
1362
- var points = getBoundingBox([position].concat(_toConsumableArray(startPoints)));
1363
- return _objectSpread2(_objectSpread2({}, state), {}, {
1364
- startPoints: startPoints,
1468
+ const points = getBoundingBox([position, ...startPoints]);
1469
+ return {
1470
+ ...state,
1471
+ startPoints,
1365
1472
  previousPolygonPoints: null,
1366
- points: points,
1473
+ points,
1367
1474
  selection: rectHandleSelection(mapIndexOfRectHandleCrossingOver(index, position, startPoints), points, selectionPosition)
1368
- });
1475
+ };
1369
1476
  }
1370
1477
  }
1371
1478
  function rectHandleSelection(index, points, selectionPosition) {
@@ -1377,7 +1484,7 @@ function rectHandleSelection(index, points, selectionPosition) {
1377
1484
  };
1378
1485
  }
1379
1486
  function constrainToAxis(index, cursor, points) {
1380
- var axis = rectHandleAxis(index);
1487
+ const axis = rectHandleAxis(index);
1381
1488
  if (axis === 'x') {
1382
1489
  return [cursor[0], points[(index - 1) / 2][1]];
1383
1490
  } else if (axis === 'y') {
@@ -1399,7 +1506,7 @@ function mapIndexOfRectHandleCrossingOver(index, position, startPoints) {
1399
1506
  return index;
1400
1507
  }
1401
1508
  function withPotentialPoint(state) {
1402
- return [].concat(_toConsumableArray(state.points.slice(0, state.potentialPointInsertIndex)), [state.potentialPoint], _toConsumableArray(state.points.slice(state.potentialPointInsertIndex)));
1509
+ return [...state.points.slice(0, state.potentialPointInsertIndex), state.potentialPoint, ...state.points.slice(state.potentialPointInsertIndex)];
1403
1510
  }
1404
1511
  function midpoint(p1, p2) {
1405
1512
  return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];
@@ -1408,14 +1515,12 @@ function getBoundingBox(polygon) {
1408
1515
  if (polygon.length === 0) {
1409
1516
  return null;
1410
1517
  }
1411
- var minX = polygon[0][0];
1412
- var minY = polygon[0][1];
1413
- var maxX = polygon[0][0];
1414
- var maxY = polygon[0][1];
1415
- for (var i = 1; i < polygon.length; i++) {
1416
- var _polygon$i = _slicedToArray(polygon[i], 2),
1417
- x = _polygon$i[0],
1418
- y = _polygon$i[1];
1518
+ let minX = polygon[0][0];
1519
+ let minY = polygon[0][1];
1520
+ let maxX = polygon[0][0];
1521
+ let maxY = polygon[0][1];
1522
+ for (let i = 1; i < polygon.length; i++) {
1523
+ let [x, y] = polygon[i];
1419
1524
  if (x < minX) minX = x;
1420
1525
  if (x > maxX) maxX = x;
1421
1526
  if (y < minY) minY = y;
@@ -1424,51 +1529,49 @@ function getBoundingBox(polygon) {
1424
1529
  return [[minX, minY], [maxX, minY], [maxX, maxY], [minX, maxY]];
1425
1530
  }
1426
1531
  function ensureInBounds(point) {
1427
- return point.map(function (coord) {
1428
- return Math.min(100, Math.max(0, coord));
1429
- });
1532
+ return point.map(coord => Math.min(100, Math.max(0, coord)));
1430
1533
  }
1431
1534
  function ensureInPolygon(polygon, point) {
1432
1535
  return isPointInPolygon(polygon, point) ? point : closestPointOnPolygon(polygon, point)[1];
1433
1536
  }
1434
1537
  function isPointInPolygon(polygon, point) {
1435
- var x = point[0],
1538
+ let x = point[0],
1436
1539
  y = point[1];
1437
- var inside = false;
1438
- for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1439
- var xi = polygon[i][0],
1540
+ let inside = false;
1541
+ for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
1542
+ let xi = polygon[i][0],
1440
1543
  yi = polygon[i][1];
1441
- var xj = polygon[j][0],
1544
+ let xj = polygon[j][0],
1442
1545
  yj = polygon[j][1];
1443
- var intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
1546
+ let intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
1444
1547
  if (intersect) inside = !inside;
1445
1548
  }
1446
1549
  return inside;
1447
1550
  }
1448
- function closestPointOnPolygon(polygon, c) {
1551
+ function closestPointOnPolygon(polygon, c, maxDistance = 5) {
1449
1552
  function distance(p1, p2) {
1450
- return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
1553
+ return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
1451
1554
  }
1452
1555
  function closestPoint(A, B, C) {
1453
- var AB = [B[0] - A[0], B[1] - A[1]];
1454
- var AC = [C[0] - A[0], C[1] - A[1]];
1455
- var abLength = AB[0] * AB[0] + AB[1] * AB[1]; // Dot product of AB with itself
1556
+ const AB = [B[0] - A[0], B[1] - A[1]];
1557
+ const AC = [C[0] - A[0], C[1] - A[1]];
1558
+ const abLength = AB[0] * AB[0] + AB[1] * AB[1]; // Dot product of AB with itself
1456
1559
 
1457
1560
  if (abLength === 0) return A; // A and B are the same points
1458
1561
 
1459
- var proj = (AC[0] * AB[0] + AC[1] * AB[1]) / abLength; // Projection ratio of AC on AB
1562
+ const proj = (AC[0] * AB[0] + AC[1] * AB[1]) / abLength; // Projection ratio of AC on AB
1460
1563
 
1461
1564
  if (proj < 0) return A; // Closer to A
1462
1565
  else if (proj > 1) return B; // Closer to B
1463
1566
  else return [A[0] + proj * AB[0], A[1] + proj * AB[1]]; // Point on the segment
1464
1567
  }
1465
- var closest = null;
1466
- var minDistance = Infinity;
1467
- for (var i = 0; i < polygon.length; i++) {
1468
- var A = polygon[i];
1469
- var B = polygon[(i + 1) % polygon.length];
1470
- var point = closestPoint(A, B, c);
1471
- var dist = distance(c, point);
1568
+ let closest = null;
1569
+ let minDistance = Infinity;
1570
+ for (let i = 0; i < polygon.length; i++) {
1571
+ const A = polygon[i];
1572
+ const B = polygon[(i + 1) % polygon.length];
1573
+ const point = closestPoint(A, B, c);
1574
+ const dist = distance(c, point);
1472
1575
  if (dist < minDistance) {
1473
1576
  minDistance = dist;
1474
1577
  closest = [i + 1, point];
@@ -1477,15 +1580,15 @@ function closestPointOnPolygon(polygon, c) {
1477
1580
  return closest;
1478
1581
  }
1479
1582
  function polygonCentroid(points) {
1480
- var centroidX = 0;
1481
- var centroidY = 0;
1482
- var signedArea = 0;
1483
- var x0 = 0;
1484
- var y0 = 0;
1485
- var x1 = 0;
1486
- var y1 = 0;
1487
- var a = 0;
1488
- for (var i = 0; i < points.length - 1; i++) {
1583
+ let centroidX = 0;
1584
+ let centroidY = 0;
1585
+ let signedArea = 0;
1586
+ let x0 = 0;
1587
+ let y0 = 0;
1588
+ let x1 = 0;
1589
+ let y1 = 0;
1590
+ let a = 0;
1591
+ for (let i = 0; i < points.length - 1; i++) {
1489
1592
  x0 = points[i][0];
1490
1593
  y0 = points[i][1];
1491
1594
  x1 = points[i + 1][0];
@@ -1509,9 +1612,7 @@ function polygonCentroid(points) {
1509
1612
  return [centroidX, centroidY];
1510
1613
  }
1511
1614
  function round(point) {
1512
- return point.map(function (coord) {
1513
- return Math.round(coord * 10) / 10;
1514
- });
1615
+ return point.map(coord => Math.round(coord * 10) / 10);
1515
1616
  }
1516
1617
 
1517
1618
  var css$1 = ".DraggableEditorView-module_wrapper__J8JLO {\n position: relative;\n display: inline-block;\n overflow: hidden;\n\n background-image:\n linear-gradient(45deg, var(--ui-on-surface-color-lighter) 25%, transparent 25%),\n linear-gradient(135deg, var(--ui-on-surface-color-lighter) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--ui-on-surface-color-lighter) 75%),\n linear-gradient(135deg, transparent 75%, var(--ui-on-surface-color-lighter) 75%);\n background-size: 16px 16px;\n background-position:0 0, 8px 0, 8px -8px, 0px 8px;\n}\n\n.DraggableEditorView-module_buttons__1Xob0 {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin: 10px 0;\n gap: 15px;\n}\n\n.DraggableEditorView-module_buttons__1Xob0 button {\n white-space: nowrap;\n}\n\n.DraggableEditorView-module_coordinates__3dVEt,\n.DraggableEditorView-module_coordinates__3dVEt label {\n display: flex;\n align-items: center;\n margin: 0;\n}\n\n.DraggableEditorView-module_coordinates__3dVEt {\n flex-wrap: wrap;\n justify-content: flex-end;\n}\n\n.DraggableEditorView-module_coordinates__3dVEt {\n gap: 10px;\n}\n\n.DraggableEditorView-module_coordinates__3dVEt label {\n gap: 5px;\n}\n\n.DraggableEditorView-module_coordinates__3dVEt input[disabled] {\n background-color: var(--ui-on-surface-color-lightest);\n}\n\n.DraggableEditorView-module_modeButtons__4wZBu {\n flex: 1;\n white-space: nowrap;\n}\n\n.DraggableEditorView-module_modeButtons__4wZBu button:first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.DraggableEditorView-module_modeButtons__4wZBu button:last-child {\n margin-left: -1px;\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.DraggableEditorView-module_modeButtons__4wZBu button[aria-pressed=true] {\n background-color: var(--ui-selection-color-light);\n}\n\n.DraggableEditorView-module_buttons__1Xob0 img {\n vertical-align: middle;\n margin-right: 6px;\n}\n\n.DraggableEditorView-module_placeholderImage__JyyId {\n aspect-ratio: 16 / 9;\n background-color: #000;\n}\n\n.DraggableEditorView-module_image__1Ockp {\n display: block;\n height: calc(100vh - 250px);\n max-height: 600px;\n min-height: 200px;\n}\n\n.DraggableEditorView-module_portraitImage__2lYIE {\n max-height: 1200px;\n}\n\n.DraggableEditorView-module_overlay__3QLpM {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n}\n\n.DraggableEditorView-module_overlay__3QLpM svg {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n\n.DraggableEditorView-module_overlay__3QLpM polygon {\n vector-effect: non-scaling-stroke;\n stroke-width: 1px;\n stroke-linejoin: round;\n stroke: #fff;\n fill: transparent;\n opacity: 0.9;\n cursor: move;\n}\n\n.DraggableEditorView-module_handle__9LHSy {\n position: absolute;\n width: 10px;\n height: 10px;\n background-color: #fff;\n transform: translate(-50%, -50%);\n border: solid 1px var(--ui-primary-color);\n border-radius: 2px;\n opacity: 0.9;\n z-index: 2;\n}\n\n.DraggableEditorView-module_handle__9LHSy::before {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: 30px;\n height: 30px;\n margin: -10px 0 0 -10px;\n border-radius: 100%;\n z-index: 1;\n}\n\n.DraggableEditorView-module_circle__35Pba {\n border-radius: 100%;\n cursor: move;\n}\n\n.DraggableEditorView-module_potential__vxrma {\n opacity: 0;\n z-index: 1;\n cursor: default;\n}\n\n.DraggableEditorView-module_handle__9LHSy:hover {\n opacity: 1;\n}\n\n.DraggableEditorView-module_indicator__23yQO {\n --size: 15px;\n position: absolute;\n left: var(--center-x);\n top: var(--center-y);\n margin: calc(var(--size) / -2) 0 0 calc(var(--size) / -2);\n border-radius: 50%;\n width: var(--size);\n height: var(--size);\n background-color: var(--color, #fff);\n transition: transform 0.2s ease;\n cursor: move;\n z-index: 3;\n}\n\n.DraggableEditorView-module_indicator__23yQO:hover {\n transform: scale(1.2);\n}\n\n.DraggableEditorView-module_indicator__23yQO::before {\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n width: var(--size);\n height: var(--size);\n border-radius: 50%;\n background-color: #fff;\n animation: DraggableEditorView-module_blink__1SdQI 1s infinite;\n opacity: 0.3;\n z-index: -1;\n}\n\n.DraggableEditorView-module_selected__2bQtv {\n box-shadow: 0 0 0 3px var(--ui-selection-color),\n 0 0 0 4px var(--ui-primary-color-light);\n}\n\n@keyframes DraggableEditorView-module_blink__1SdQI {\n 0% {\n transform: scale(1.7);\n }\n\n 50% {\n transform: scale(2);\n }\n\n 100% {\n transform: scale(1.7);\n }\n}\n";
@@ -1524,11 +1625,11 @@ var img$b = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBo
1524
1625
 
1525
1626
  var img$c = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' version='1.1'%3e %3cpath d='m 243%2c25.5 c -3%2c3.6 -6%2c8.5 -6%2c14 V 129 l -8%2c-7 c -7%2c-8 -20%2c-8 -28%2c0 -7%2c7 -7%2c19 0%2c26 l 42%2c42 v 0 c 2%2c2 4%2c3 6%2c4 3%2c1 5%2c1 8%2c2 v 0 c 5%2c-1 10%2c-2 14%2c-6 l 41%2c-42 c 7%2c-7 7%2c-19 0%2c-26 -8%2c-8 -20%2c-8 -28%2c0 l -8%2c7 V 38.9 C 276%2c28.5 268%2c20 257%2c20 c -6%2c0 -11%2c2.4 -14%2c5.5 z' style='stroke-width:0.608' /%3e %3cpath d='m 486%2c243 c -4%2c-3 -8%2c-6 -14%2c-6 h -89 l 7%2c-8 c 8%2c-7 8%2c-21 0%2c-29 -7%2c-7 -19%2c-7 -26%2c0 l -42%2c43 v 0 c -2%2c2 -3%2c4 -4%2c6 -1%2c3 -1%2c5 -2%2c8 v 0 c 1%2c5 2%2c10 6%2c14 l 42%2c41 c 7%2c7 19%2c7 26%2c0 8%2c-8 8%2c-20 0%2c-28 l -7%2c-8 h 90 c 10%2c0 19%2c-8 19%2c-19 0%2c-6 -3%2c-11 -6%2c-14 z' style='stroke-width:0.608' /%3e %3cpath d='m 269%2c486 c 3%2c-4 6%2c-8 6%2c-14 v -89 l 8%2c7 c 7%2c8 21%2c8 29%2c0 7%2c-7 7%2c-19 0%2c-26 l -43%2c-42 v 0 c -2%2c-2 -4%2c-3 -6%2c-4 -3%2c-1 -5%2c-1 -8%2c-2 v 0 c -5%2c1 -10%2c2 -14%2c6 l -41%2c42 c -7%2c7 -7%2c19 0%2c26 8%2c8 20%2c8 28%2c0 l 8%2c-7 v 90 c 0%2c10 8%2c19 19%2c19 6%2c0 11%2c-3 14%2c-6 z' style='stroke-width:0.608' /%3e %3cpath d='m 26%2c269 c 4%2c3 8%2c6 14%2c6 h 89 l -7%2c8 c -8%2c7 -8%2c21 0%2c29 7%2c7 19%2c7 26%2c0 l 42%2c-43 v 0 c 2%2c-2 3%2c-4 4%2c-6 1%2c-3 1%2c-5 2%2c-8 v 0 c -1%2c-5 -2%2c-10 -6%2c-14 l -42%2c-41 c -7%2c-7 -19%2c-7 -26%2c0 -8%2c8 -8%2c20 0%2c28 l 7%2c8 H 39 c -10%2c0 -19%2c8 -19%2c19 0%2c6 3%2c11 6%2c14 z' style='stroke-width:0.608' /%3e%3c/svg%3e";
1526
1627
 
1527
- var i18nPrefix = 'pageflow_scrolled.editor.content_elements.hotspots.edit_area_dialog';
1528
- var DraggableEditorView = Marionette.View.extend({
1529
- render: function render() {
1530
- var _this$options$file,
1531
- _this = this;
1628
+ var _jsxFileName = "/home/tfischbach/code/pageflow/entry_types/scrolled/package/src/contentElements/hotspots/editor/EditAreaDialogView/DraggableEditorView.js";
1629
+ const i18nPrefix = 'pageflow_scrolled.editor.content_elements.hotspots.edit_area_dialog';
1630
+ const DraggableEditorView = Marionette.View.extend({
1631
+ render() {
1632
+ var _this$options$file;
1532
1633
  ReactDOM.render( /*#__PURE__*/React.createElement(DraggableEditor, {
1533
1634
  imageSrc: (_this$options$file = this.options.file) === null || _this$options$file === void 0 ? void 0 : _this$options$file.getBackgroundPositioningImageUrl(),
1534
1635
  portrait: this.options.file && this.options.file.get('width') < this.options.file.get('height'),
@@ -1536,19 +1637,19 @@ var DraggableEditorView = Marionette.View.extend({
1536
1637
  initialMode: this.model.get(this.getPropertyName('mode')),
1537
1638
  initialPoints: this.model.get(this.getPropertyName('outline')),
1538
1639
  initialIndicatorPosition: this.model.get(this.getPropertyName('indicatorPosition')),
1539
- onModeChange: function onModeChange(mode) {
1540
- return _this.mode = mode;
1541
- },
1542
- onPointsChange: function onPointsChange(points) {
1543
- return _this.points = points;
1544
- },
1545
- onIndicatorPositionChange: function onIndicatorPositionChange(indicatorPosition) {
1546
- return _this.indicatorPosition = indicatorPosition;
1640
+ onModeChange: mode => this.mode = mode,
1641
+ onPointsChange: points => this.points = points,
1642
+ onIndicatorPositionChange: indicatorPosition => this.indicatorPosition = indicatorPosition,
1643
+ __self: this,
1644
+ __source: {
1645
+ fileName: _jsxFileName,
1646
+ lineNumber: 42,
1647
+ columnNumber: 7
1547
1648
  }
1548
1649
  }), this.el);
1549
1650
  return this;
1550
1651
  },
1551
- save: function save() {
1652
+ save() {
1552
1653
  if (this.mode) {
1553
1654
  this.model.set(this.getPropertyName('mode'), this.mode);
1554
1655
  }
@@ -1559,108 +1660,171 @@ var DraggableEditorView = Marionette.View.extend({
1559
1660
  this.model.set(this.getPropertyName('indicatorPosition'), this.indicatorPosition);
1560
1661
  }
1561
1662
  },
1562
- getPropertyName: function getPropertyName(suffix) {
1563
- return this.options.portrait ? "portrait".concat(utils.capitalize(suffix)) : suffix;
1663
+ getPropertyName(suffix) {
1664
+ return this.options.portrait ? `portrait${utils.capitalize(suffix)}` : suffix;
1564
1665
  }
1565
1666
  });
1566
- function DraggableEditor(_ref) {
1667
+ function DraggableEditor({
1668
+ imageSrc,
1669
+ portrait,
1670
+ indicatorColor,
1671
+ initialMode,
1672
+ initialPoints,
1673
+ initialIndicatorPosition,
1674
+ onModeChange,
1675
+ onPointsChange,
1676
+ onIndicatorPositionChange
1677
+ }) {
1567
1678
  var _state$selection2, _state$selection3;
1568
- var imageSrc = _ref.imageSrc,
1569
- portrait = _ref.portrait,
1570
- indicatorColor = _ref.indicatorColor,
1571
- initialMode = _ref.initialMode,
1572
- initialPoints = _ref.initialPoints,
1573
- initialIndicatorPosition = _ref.initialIndicatorPosition,
1574
- onModeChange = _ref.onModeChange,
1575
- onPointsChange = _ref.onPointsChange,
1576
- onIndicatorPositionChange = _ref.onIndicatorPositionChange;
1577
- var _useReducer = useReducer(reducer, {
1578
- mode: initialMode || 'rect',
1579
- points: initialPoints || [[40, 40], [60, 40], [60, 60], [40, 60]],
1580
- indicatorPosition: initialIndicatorPosition || [50, 50]
1581
- }),
1582
- _useReducer2 = _slicedToArray(_useReducer, 2),
1583
- state = _useReducer2[0],
1584
- dispatch = _useReducer2[1];
1585
- var mode = state.mode,
1586
- points = state.points,
1587
- potentialPoint = state.potentialPoint,
1588
- indicatorPosition = state.indicatorPosition,
1589
- selection = state.selection;
1590
- useEffect(function () {
1679
+ const [state, dispatch] = useReducer(reducer, {
1680
+ mode: initialMode || 'rect',
1681
+ points: initialPoints || [[40, 40], [60, 40], [60, 60], [40, 60]],
1682
+ indicatorPosition: initialIndicatorPosition || [50, 50]
1683
+ });
1684
+ const {
1685
+ mode,
1686
+ points,
1687
+ potentialPoint,
1688
+ indicatorPosition,
1689
+ selection
1690
+ } = state;
1691
+ useEffect(() => {
1591
1692
  onModeChange(mode);
1592
1693
  }, [onModeChange, mode]);
1593
- useEffect(function () {
1694
+ useEffect(() => {
1594
1695
  onPointsChange(points);
1595
1696
  }, [onPointsChange, points]);
1596
- useEffect(function () {
1697
+ useEffect(() => {
1597
1698
  onIndicatorPositionChange(indicatorPosition);
1598
1699
  }, [onIndicatorPositionChange, indicatorPosition]);
1599
- var ref = useRef();
1700
+ const ref = useRef();
1600
1701
  function clientToPercent(event) {
1601
- var rect = ref.current.getBoundingClientRect();
1702
+ const rect = ref.current.getBoundingClientRect();
1602
1703
  return [Math.max(0, Math.min(100, (event.clientX - rect.left) / rect.width * 100)), Math.max(0, Math.min(100, (event.clientY - rect.top) / rect.height * 100))];
1603
1704
  }
1604
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
1605
- className: styles$1.buttons
1705
+ return /*#__PURE__*/React.createElement("div", {
1706
+ __self: this,
1707
+ __source: {
1708
+ fileName: _jsxFileName,
1709
+ lineNumber: 121,
1710
+ columnNumber: 5
1711
+ }
1712
+ }, /*#__PURE__*/React.createElement("div", {
1713
+ className: styles$1.buttons,
1714
+ __self: this,
1715
+ __source: {
1716
+ fileName: _jsxFileName,
1717
+ lineNumber: 122,
1718
+ columnNumber: 7
1719
+ }
1606
1720
  }, /*#__PURE__*/React.createElement(ModeButtons, {
1607
1721
  mode: mode,
1608
- dispatch: dispatch
1722
+ dispatch: dispatch,
1723
+ __self: this,
1724
+ __source: {
1725
+ fileName: _jsxFileName,
1726
+ lineNumber: 123,
1727
+ columnNumber: 9
1728
+ }
1609
1729
  }), /*#__PURE__*/React.createElement(Coordinates, {
1610
1730
  selection: selection,
1611
- onChange: function onChange(position) {
1612
- return dispatch({
1613
- type: UPDATE_SELECTION_POSITION,
1614
- position: position
1615
- });
1616
- },
1617
- onBlur: function onBlur() {
1618
- return dispatch({
1619
- type: BLUR_SELECTION_POSITION
1620
- });
1731
+ onChange: position => dispatch({
1732
+ type: UPDATE_SELECTION_POSITION,
1733
+ position
1734
+ }),
1735
+ onBlur: () => dispatch({
1736
+ type: BLUR_SELECTION_POSITION
1737
+ }),
1738
+ __self: this,
1739
+ __source: {
1740
+ fileName: _jsxFileName,
1741
+ lineNumber: 124,
1742
+ columnNumber: 9
1621
1743
  }
1622
1744
  }), /*#__PURE__*/React.createElement(CenterIndicatorButton, {
1623
- onClick: function onClick() {
1624
- return dispatch({
1625
- type: CENTER_INDICATOR
1626
- });
1745
+ onClick: () => dispatch({
1746
+ type: CENTER_INDICATOR
1747
+ }),
1748
+ __self: this,
1749
+ __source: {
1750
+ fileName: _jsxFileName,
1751
+ lineNumber: 132,
1752
+ columnNumber: 9
1627
1753
  }
1628
1754
  })), /*#__PURE__*/React.createElement("div", {
1629
- className: styles$1.wrapper
1755
+ className: styles$1.wrapper,
1756
+ __self: this,
1757
+ __source: {
1758
+ fileName: _jsxFileName,
1759
+ lineNumber: 137,
1760
+ columnNumber: 7
1761
+ }
1630
1762
  }, imageSrc ? /*#__PURE__*/React.createElement("img", {
1631
- className: classNames(styles$1.image, _defineProperty({}, styles$1.portraitImage, portrait)),
1763
+ className: classNames(styles$1.image, {
1764
+ [styles$1.portraitImage]: portrait
1765
+ }),
1632
1766
  src: imageSrc,
1633
- alt: I18n.t("".concat(i18nPrefix, ".hotspots_image"))
1767
+ alt: I18n.t(`${i18nPrefix}.hotspots_image`),
1768
+ __self: this,
1769
+ __source: {
1770
+ fileName: _jsxFileName,
1771
+ lineNumber: 139,
1772
+ columnNumber: 10
1773
+ }
1634
1774
  }) : /*#__PURE__*/React.createElement("div", {
1635
- className: classNames(styles$1.image, styles$1.placeholderImage)
1775
+ className: classNames(styles$1.image, styles$1.placeholderImage),
1776
+ __self: this,
1777
+ __source: {
1778
+ fileName: _jsxFileName,
1779
+ lineNumber: 142,
1780
+ columnNumber: 10
1781
+ }
1636
1782
  }), /*#__PURE__*/React.createElement("div", {
1637
1783
  ref: ref,
1638
1784
  className: styles$1.overlay,
1639
- onMouseMove: function onMouseMove(event) {
1640
- return dispatch({
1641
- type: MOUSE_MOVE,
1642
- cursor: clientToPercent(event)
1643
- });
1785
+ onMouseMove: event => dispatch({
1786
+ type: MOUSE_MOVE,
1787
+ cursor: clientToPercent(event)
1788
+ }),
1789
+ __self: this,
1790
+ __source: {
1791
+ fileName: _jsxFileName,
1792
+ lineNumber: 143,
1793
+ columnNumber: 9
1644
1794
  }
1645
1795
  }, /*#__PURE__*/React.createElement("svg", {
1646
1796
  xmlns: "http://www.w3.org/2000/svg",
1647
1797
  viewBox: "0 0 100 100",
1648
- preserveAspectRatio: "none"
1798
+ preserveAspectRatio: "none",
1799
+ __self: this,
1800
+ __source: {
1801
+ fileName: _jsxFileName,
1802
+ lineNumber: 146,
1803
+ columnNumber: 11
1804
+ }
1649
1805
  }, /*#__PURE__*/React.createElement(DraggableCore, {
1650
- onDrag: function onDrag(event, dragEvent) {
1651
- var rect = ref.current.getBoundingClientRect();
1806
+ onDrag: (event, dragEvent) => {
1807
+ const rect = ref.current.getBoundingClientRect();
1652
1808
  dispatch({
1653
1809
  type: DRAG,
1654
1810
  delta: [dragEvent.deltaX / rect.width * 100, dragEvent.deltaY / rect.height * 100]
1655
1811
  });
1812
+ },
1813
+ __self: this,
1814
+ __source: {
1815
+ fileName: _jsxFileName,
1816
+ lineNumber: 147,
1817
+ columnNumber: 13
1656
1818
  }
1657
1819
  }, /*#__PURE__*/React.createElement("polygon", {
1658
- points: drawnOutlinePoints(state).map(function (coords) {
1659
- return coords.map(function (coord) {
1660
- return coord;
1661
- }).join(',');
1662
- }).join(' ')
1663
- }))), handles(state).map(function (handle, index) {
1820
+ points: drawnOutlinePoints(state).map(coords => coords.map(coord => coord).join(',')).join(' '),
1821
+ __self: this,
1822
+ __source: {
1823
+ fileName: _jsxFileName,
1824
+ lineNumber: 158,
1825
+ columnNumber: 15
1826
+ }
1827
+ }))), handles(state).map((handle, index) => {
1664
1828
  var _state$selection;
1665
1829
  return /*#__PURE__*/React.createElement(Handle, {
1666
1830
  key: index,
@@ -1669,30 +1833,28 @@ function DraggableEditor(_ref) {
1669
1833
  axis: handle.axis,
1670
1834
  cursor: handle.cursor,
1671
1835
  circle: handle.circle,
1672
- title: handle.deletable ? I18n.t("".concat(i18nPrefix, ".double_click_to_delete")) : null,
1673
- onClick: function onClick(event) {
1674
- return dispatch({
1675
- type: CLICK_HANDLE,
1676
- index: index
1677
- });
1678
- },
1679
- onDoubleClick: function onDoubleClick(event) {
1680
- return dispatch({
1681
- type: DOUBLE_CLICK_HANDLE,
1682
- index: index
1683
- });
1684
- },
1685
- onDrag: function onDrag(event) {
1686
- return dispatch({
1687
- type: DRAG_HANDLE,
1688
- index: index,
1689
- cursor: clientToPercent(event)
1690
- });
1691
- },
1692
- onDragStop: function onDragStop(event) {
1693
- return dispatch({
1694
- type: DRAG_HANDLE_STOP
1695
- });
1836
+ title: handle.deletable ? I18n.t(`${i18nPrefix}.double_click_to_delete`) : null,
1837
+ onClick: event => dispatch({
1838
+ type: CLICK_HANDLE,
1839
+ index
1840
+ }),
1841
+ onDoubleClick: event => dispatch({
1842
+ type: DOUBLE_CLICK_HANDLE,
1843
+ index
1844
+ }),
1845
+ onDrag: event => dispatch({
1846
+ type: DRAG_HANDLE,
1847
+ index,
1848
+ cursor: clientToPercent(event)
1849
+ }),
1850
+ onDragStop: event => dispatch({
1851
+ type: DRAG_HANDLE_STOP
1852
+ }),
1853
+ __self: this,
1854
+ __source: {
1855
+ fileName: _jsxFileName,
1856
+ lineNumber: 165,
1857
+ columnNumber: 13
1696
1858
  }
1697
1859
  });
1698
1860
  }), potentialPoint && /*#__PURE__*/React.createElement(Handle, {
@@ -1700,189 +1862,304 @@ function DraggableEditor(_ref) {
1700
1862
  circle: true,
1701
1863
  potential: true,
1702
1864
  selected: ((_state$selection2 = state.selection) === null || _state$selection2 === void 0 ? void 0 : _state$selection2.type) === 'potentialPoint',
1703
- onDrag: function onDrag(event) {
1704
- return dispatch({
1705
- type: DRAG_POTENTIAL_POINT,
1706
- cursor: clientToPercent(event)
1707
- });
1708
- },
1709
- onDragStop: function onDragStop(event) {
1710
- return dispatch({
1711
- type: DRAG_POTENTIAL_POINT_STOP
1712
- });
1865
+ onDrag: event => dispatch({
1866
+ type: DRAG_POTENTIAL_POINT,
1867
+ cursor: clientToPercent(event)
1868
+ }),
1869
+ onDragStop: event => dispatch({
1870
+ type: DRAG_POTENTIAL_POINT_STOP
1871
+ }),
1872
+ __self: this,
1873
+ __source: {
1874
+ fileName: _jsxFileName,
1875
+ lineNumber: 191,
1876
+ columnNumber: 30
1713
1877
  }
1714
1878
  }), /*#__PURE__*/React.createElement(Indicator, {
1715
1879
  position: indicatorPosition,
1716
1880
  selected: ((_state$selection3 = state.selection) === null || _state$selection3 === void 0 ? void 0 : _state$selection3.type) === 'indicator',
1717
1881
  color: indicatorColor,
1718
- onClick: function onClick(event) {
1719
- return dispatch({
1720
- type: CLICK_INDICATOR
1721
- });
1722
- },
1723
- onDrag: function onDrag(event) {
1724
- return dispatch({
1725
- type: DRAG_INDICATOR,
1726
- cursor: clientToPercent(event)
1727
- });
1882
+ onClick: event => dispatch({
1883
+ type: CLICK_INDICATOR
1884
+ }),
1885
+ onDrag: event => dispatch({
1886
+ type: DRAG_INDICATOR,
1887
+ cursor: clientToPercent(event)
1888
+ }),
1889
+ __self: this,
1890
+ __source: {
1891
+ fileName: _jsxFileName,
1892
+ lineNumber: 203,
1893
+ columnNumber: 11
1728
1894
  }
1729
1895
  }))));
1730
1896
  }
1731
- var modeIcons = {
1897
+ const modeIcons = {
1732
1898
  rect: img$a,
1733
1899
  polygon: img$b
1734
1900
  };
1735
- function ModeButtons(_ref2) {
1736
- var mode = _ref2.mode,
1737
- dispatch = _ref2.dispatch;
1901
+ function ModeButtons({
1902
+ mode,
1903
+ dispatch
1904
+ }) {
1738
1905
  return /*#__PURE__*/React.createElement("div", {
1739
- className: styles$1.modeButtons
1740
- }, ['rect', 'polygon'].map(function (availableMode) {
1741
- return /*#__PURE__*/React.createElement("button", {
1742
- key: availableMode,
1743
- type: "button",
1744
- className: buttonStyles.secondaryIconButton,
1745
- "aria-pressed": mode === availableMode,
1746
- onClick: function onClick() {
1747
- return dispatch({
1748
- type: SET_MODE,
1749
- value: availableMode
1750
- });
1751
- }
1752
- }, /*#__PURE__*/React.createElement("img", {
1753
- src: modeIcons[availableMode],
1754
- alt: "",
1755
- width: "20",
1756
- height: "20"
1757
- }), I18n.t(availableMode, {
1758
- scope: "".concat(i18nPrefix, ".modes")
1759
- }));
1760
- }));
1906
+ className: styles$1.modeButtons,
1907
+ __self: this,
1908
+ __source: {
1909
+ fileName: _jsxFileName,
1910
+ lineNumber: 226,
1911
+ columnNumber: 5
1912
+ }
1913
+ }, ['rect', 'polygon'].map(availableMode => /*#__PURE__*/React.createElement("button", {
1914
+ key: availableMode,
1915
+ type: "button",
1916
+ className: buttonStyles.secondaryIconButton,
1917
+ "aria-pressed": mode === availableMode,
1918
+ onClick: () => dispatch({
1919
+ type: SET_MODE,
1920
+ value: availableMode
1921
+ }),
1922
+ __self: this,
1923
+ __source: {
1924
+ fileName: _jsxFileName,
1925
+ lineNumber: 228,
1926
+ columnNumber: 9
1927
+ }
1928
+ }, /*#__PURE__*/React.createElement("img", {
1929
+ src: modeIcons[availableMode],
1930
+ alt: "",
1931
+ width: "20",
1932
+ height: "20",
1933
+ __self: this,
1934
+ __source: {
1935
+ fileName: _jsxFileName,
1936
+ lineNumber: 233,
1937
+ columnNumber: 11
1938
+ }
1939
+ }), I18n.t(availableMode, {
1940
+ scope: `${i18nPrefix}.modes`
1941
+ }))));
1761
1942
  }
1762
- function Handle(_ref3) {
1763
- var point = _ref3.point,
1764
- selected = _ref3.selected,
1765
- circle = _ref3.circle,
1766
- potential = _ref3.potential,
1767
- title = _ref3.title,
1768
- cursor = _ref3.cursor,
1769
- onDrag = _ref3.onDrag,
1770
- onDragStop = _ref3.onDragStop,
1771
- onClick = _ref3.onClick,
1772
- onDoubleClick = _ref3.onDoubleClick;
1943
+ function Handle({
1944
+ point,
1945
+ selected,
1946
+ circle,
1947
+ potential,
1948
+ title,
1949
+ cursor,
1950
+ onDrag,
1951
+ onDragStop,
1952
+ onClick,
1953
+ onDoubleClick
1954
+ }) {
1773
1955
  return /*#__PURE__*/React.createElement(DraggableCore, {
1774
1956
  onDrag: onDrag,
1775
- onStop: onDragStop
1957
+ onStop: onDragStop,
1958
+ __self: this,
1959
+ __source: {
1960
+ fileName: _jsxFileName,
1961
+ lineNumber: 244,
1962
+ columnNumber: 5
1963
+ }
1776
1964
  }, /*#__PURE__*/React.createElement("div", {
1777
- className: classNames(styles$1.handle, _defineProperty(_defineProperty(_defineProperty({}, styles$1.circle, circle), styles$1.selected, selected), styles$1.potential, potential)),
1965
+ className: classNames(styles$1.handle, {
1966
+ [styles$1.circle]: circle,
1967
+ [styles$1.selected]: selected,
1968
+ [styles$1.potential]: potential
1969
+ }),
1778
1970
  tabIndex: "0",
1779
1971
  onClick: onClick,
1780
1972
  onDoubleClick: onDoubleClick,
1781
1973
  title: title,
1782
1974
  style: {
1783
- left: "".concat(point[0], "%"),
1784
- top: "".concat(point[1], "%"),
1785
- cursor: cursor
1975
+ left: `${point[0]}%`,
1976
+ top: `${point[1]}%`,
1977
+ cursor
1978
+ },
1979
+ __self: this,
1980
+ __source: {
1981
+ fileName: _jsxFileName,
1982
+ lineNumber: 246,
1983
+ columnNumber: 7
1786
1984
  }
1787
1985
  }));
1788
1986
  }
1789
- function Indicator(_ref4) {
1790
- var position = _ref4.position,
1791
- selected = _ref4.selected,
1792
- color = _ref4.color,
1793
- onClick = _ref4.onClick,
1794
- onDrag = _ref4.onDrag;
1987
+ function Indicator({
1988
+ position,
1989
+ selected,
1990
+ color,
1991
+ onClick,
1992
+ onDrag
1993
+ }) {
1795
1994
  return /*#__PURE__*/React.createElement(DraggableCore, {
1796
- onDrag: onDrag
1995
+ onDrag: onDrag,
1996
+ __self: this,
1997
+ __source: {
1998
+ fileName: _jsxFileName,
1999
+ lineNumber: 261,
2000
+ columnNumber: 5
2001
+ }
1797
2002
  }, /*#__PURE__*/React.createElement("div", {
1798
- className: classNames(styles$1.indicator, _defineProperty({}, styles$1.selected, selected)),
2003
+ className: classNames(styles$1.indicator, {
2004
+ [styles$1.selected]: selected
2005
+ }),
1799
2006
  onClick: onClick,
1800
2007
  style: {
1801
- left: "".concat(position[0], "%"),
1802
- top: "".concat(position[1], "%"),
2008
+ left: `${position[0]}%`,
2009
+ top: `${position[1]}%`,
1803
2010
  '--color': color
1804
2011
  },
1805
- title: I18n.t("".concat(i18nPrefix, ".indicator_title"))
2012
+ title: I18n.t(`${i18nPrefix}.indicator_title`),
2013
+ __self: this,
2014
+ __source: {
2015
+ fileName: _jsxFileName,
2016
+ lineNumber: 262,
2017
+ columnNumber: 7
2018
+ }
1806
2019
  }));
1807
2020
  }
1808
- function CenterIndicatorButton(_ref5) {
1809
- var onClick = _ref5.onClick;
2021
+ function CenterIndicatorButton({
2022
+ onClick
2023
+ }) {
1810
2024
  return /*#__PURE__*/React.createElement("button", {
1811
2025
  type: "button",
1812
2026
  className: buttonStyles.secondaryIconButton,
1813
- onClick: onClick
2027
+ onClick: onClick,
2028
+ __self: this,
2029
+ __source: {
2030
+ fileName: _jsxFileName,
2031
+ lineNumber: 276,
2032
+ columnNumber: 5
2033
+ }
1814
2034
  }, /*#__PURE__*/React.createElement("img", {
1815
2035
  src: img$c,
1816
2036
  alt: "",
1817
2037
  width: "20",
1818
- height: "20"
1819
- }), I18n.t("".concat(i18nPrefix, ".centerIndicator")));
2038
+ height: "20",
2039
+ __self: this,
2040
+ __source: {
2041
+ fileName: _jsxFileName,
2042
+ lineNumber: 279,
2043
+ columnNumber: 7
2044
+ }
2045
+ }), I18n.t(`${i18nPrefix}.centerIndicator`));
1820
2046
  }
1821
- function Coordinates(_ref6) {
1822
- var selection = _ref6.selection,
1823
- _onChange = _ref6.onChange,
1824
- onBlur = _ref6.onBlur;
2047
+ function Coordinates({
2048
+ selection,
2049
+ onChange,
2050
+ onBlur
2051
+ }) {
1825
2052
  if (!selection) {
1826
2053
  return null;
1827
2054
  }
1828
- var position = selection.position;
2055
+ const position = selection.position;
1829
2056
  return /*#__PURE__*/React.createElement("div", {
1830
- className: styles$1.coordinates
2057
+ className: styles$1.coordinates,
2058
+ __self: this,
2059
+ __source: {
2060
+ fileName: _jsxFileName,
2061
+ lineNumber: 293,
2062
+ columnNumber: 5
2063
+ }
1831
2064
  }, /*#__PURE__*/React.createElement(CoordinateInput, {
1832
2065
  label: "X",
1833
2066
  disabled: selection.axis === 'y',
1834
2067
  value: position[0],
1835
- onChange: function onChange(event) {
1836
- return _onChange([parseFloat(event.target.value || 0), position[1]]);
1837
- },
1838
- onBlur: onBlur
2068
+ onChange: event => onChange([parseFloat(event.target.value || 0), position[1]]),
2069
+ onBlur: onBlur,
2070
+ __self: this,
2071
+ __source: {
2072
+ fileName: _jsxFileName,
2073
+ lineNumber: 294,
2074
+ columnNumber: 7
2075
+ }
1839
2076
  }), /*#__PURE__*/React.createElement(CoordinateInput, {
1840
2077
  label: "Y",
1841
2078
  disabled: selection.axis === 'x',
1842
2079
  value: position[1],
1843
- onChange: function onChange(event) {
1844
- return _onChange([position[0], parseFloat(event.target.value || 0)]);
1845
- },
1846
- onBlur: onBlur
2080
+ onChange: event => onChange([position[0], parseFloat(event.target.value || 0)]),
2081
+ onBlur: onBlur,
2082
+ __self: this,
2083
+ __source: {
2084
+ fileName: _jsxFileName,
2085
+ lineNumber: 299,
2086
+ columnNumber: 7
2087
+ }
1847
2088
  }));
1848
2089
  }
1849
- function CoordinateInput(_ref7) {
1850
- var disabled = _ref7.disabled,
1851
- label = _ref7.label,
1852
- value = _ref7.value,
1853
- onChange = _ref7.onChange,
1854
- onBlur = _ref7.onBlur;
2090
+ function CoordinateInput({
2091
+ disabled,
2092
+ label,
2093
+ value,
2094
+ onChange,
2095
+ onBlur
2096
+ }) {
1855
2097
  return /*#__PURE__*/React.createElement("div", {
1856
2098
  className: classNames({
1857
2099
  'input-disabled': disabled
1858
- })
1859
- }, /*#__PURE__*/React.createElement("label", null, label, ":", /*#__PURE__*/React.createElement("input", {
2100
+ }),
2101
+ __self: this,
2102
+ __source: {
2103
+ fileName: _jsxFileName,
2104
+ lineNumber: 310,
2105
+ columnNumber: 5
2106
+ }
2107
+ }, /*#__PURE__*/React.createElement("label", {
2108
+ __self: this,
2109
+ __source: {
2110
+ fileName: _jsxFileName,
2111
+ lineNumber: 311,
2112
+ columnNumber: 7
2113
+ }
2114
+ }, label, ":", /*#__PURE__*/React.createElement("input", {
1860
2115
  type: "number",
1861
2116
  min: "0",
1862
2117
  max: "100",
1863
2118
  disabled: disabled,
1864
2119
  value: value,
1865
- onClick: function onClick(event) {
1866
- return event.target.focus();
1867
- },
2120
+ onClick: event => event.target.focus(),
1868
2121
  onChange: onChange,
1869
- onBlur: onBlur
2122
+ onBlur: onBlur,
2123
+ __self: this,
2124
+ __source: {
2125
+ fileName: _jsxFileName,
2126
+ lineNumber: 313,
2127
+ columnNumber: 9
2128
+ }
1870
2129
  }), "%"));
1871
2130
  }
1872
2131
 
1873
- var css$2 = ".EditAreaDialogView-module_box__1IOYj {\n width: -moz-min-content;\n width: min-content;\n min-height: 310px;\n min-width: 400px;\n}\n\n.EditAreaDialogView-module_wrapper__F28hP {}\n\n.EditAreaDialogView-module_save__1o3Qg {}\n";
2132
+ var css$2 = ".EditAreaDialogView-module_box__1IOYj {\n width: min-content;\n min-height: 310px;\n min-width: 400px;\n}\n\n.EditAreaDialogView-module_wrapper__F28hP {}\n\n.EditAreaDialogView-module_save__1o3Qg {}\n";
1874
2133
  var styles$2 = {"box":"EditAreaDialogView-module_box__1IOYj","wrapper":"EditAreaDialogView-module_wrapper__F28hP","save":"EditAreaDialogView-module_save__1o3Qg"};
1875
2134
  styleInject(css$2);
1876
2135
 
1877
- var i18nPrefix$1 = 'pageflow_scrolled.editor.content_elements.hotspots.edit_area_dialog';
1878
- var EditAreaDialogView = Marionette.ItemView.extend({
1879
- template: function template() {
1880
- return "\n <div class=\"".concat(dialogViewStyles.backdrop, "\">\n <div class=\"editor ").concat(dialogViewStyles.box, " ").concat(styles$2.box, "\">\n <h1 class=\"").concat(dialogViewStyles.header, "\">\n ").concat(I18n.t("".concat(i18nPrefix$1, ".header")), "\n </h1>\n\n <div class=\"").concat(styles$2.wrapper, "\">\n </div>\n\n <div class=\"").concat(dialogViewStyles.footer, "\">\n <button class=\"").concat(styles$2.save, " ").concat(buttonStyles.saveButton, "\">\n ").concat(I18n.t("".concat(i18nPrefix$1, ".save")), "\n </button>\n <button class=\"").concat(dialogViewStyles.close, "\">\n ").concat(I18n.t("".concat(i18nPrefix$1, ".cancel")), "\n </button>\n </div>\n </div>\n </div>\n ");
1881
- },
2136
+ const i18nPrefix$1 = 'pageflow_scrolled.editor.content_elements.hotspots.edit_area_dialog';
2137
+ const EditAreaDialogView = Marionette.ItemView.extend({
2138
+ template: () => `
2139
+ <div class="${dialogViewStyles.backdrop}">
2140
+ <div class="editor ${dialogViewStyles.box} ${styles$2.box}">
2141
+ <h1 class="${dialogViewStyles.header}">
2142
+ ${I18n.t(`${i18nPrefix$1}.header`)}
2143
+ </h1>
2144
+
2145
+ <div class="${styles$2.wrapper}">
2146
+ </div>
2147
+
2148
+ <div class="${dialogViewStyles.footer}">
2149
+ <button class="${styles$2.save} ${buttonStyles.saveButton}">
2150
+ ${I18n.t(`${i18nPrefix$1}.save`)}
2151
+ </button>
2152
+ <button class="${dialogViewStyles.close}">
2153
+ ${I18n.t(`${i18nPrefix$1}.cancel`)}
2154
+ </button>
2155
+ </div>
2156
+ </div>
2157
+ </div>
2158
+ `,
1882
2159
  mixins: [dialogView],
1883
2160
  ui: cssModulesUtils$1.ui(styles$2, 'wrapper'),
1884
2161
  events: cssModulesUtils$1.events(styles$2, {
1885
- 'click save': function clickSave() {
2162
+ 'click save': function () {
1886
2163
  this.save();
1887
2164
  this.close();
1888
2165
  if (this.options.onSave) {
@@ -1890,11 +2167,10 @@ var EditAreaDialogView = Marionette.ItemView.extend({
1890
2167
  }
1891
2168
  }
1892
2169
  }),
1893
- onRender: function onRender() {
1894
- var _this = this;
2170
+ onRender() {
1895
2171
  if (this.options.portraitFile) {
1896
- var tabsView = new TabsView({
1897
- translationKeyPrefixes: ["".concat(i18nPrefix$1, ".tabs")],
2172
+ const tabsView = new TabsView({
2173
+ translationKeyPrefixes: [`${i18nPrefix$1}.tabs`],
1898
2174
  defaultTab: this.options.defaultTab
1899
2175
  });
1900
2176
  this.editorViews = [new DraggableEditorView({
@@ -1905,13 +2181,9 @@ var EditAreaDialogView = Marionette.ItemView.extend({
1905
2181
  file: this.options.portraitFile,
1906
2182
  portrait: true
1907
2183
  })];
1908
- tabsView.tab('default', function () {
1909
- return _this.editorViews[0];
1910
- });
1911
- tabsView.tab('portrait', function () {
1912
- return _this.editorViews[1];
1913
- });
1914
- this.appendSubview(tabsView.render(), {
2184
+ tabsView.tab('default', () => this.editorViews[0]);
2185
+ tabsView.tab('portrait', () => this.editorViews[1]);
2186
+ this.appendSubview(tabsView, {
1915
2187
  to: this.ui.wrapper
1916
2188
  });
1917
2189
  } else {
@@ -1919,42 +2191,40 @@ var EditAreaDialogView = Marionette.ItemView.extend({
1919
2191
  model: this.model,
1920
2192
  file: this.options.file
1921
2193
  })];
1922
- this.appendSubview(this.editorViews[0].render(), {
2194
+ this.appendSubview(this.editorViews[0], {
1923
2195
  to: this.ui.wrapper
1924
2196
  });
1925
2197
  }
1926
2198
  },
1927
- save: function save() {
1928
- this.editorViews.forEach(function (view) {
1929
- return view.save();
1930
- });
2199
+ save() {
2200
+ this.editorViews.forEach(view => view.save());
1931
2201
  }
1932
2202
  });
1933
2203
  EditAreaDialogView.show = function (options) {
1934
2204
  app.dialogRegion.show(new EditAreaDialogView(options));
1935
2205
  };
1936
2206
 
1937
- var Area = Backbone.Model.extend({
2207
+ const Area = Backbone.Model.extend({
1938
2208
  mixins: [transientReferences],
1939
- thumbnailFile: function thumbnailFile() {
2209
+ thumbnailFile() {
1940
2210
  var _this$imageFile;
1941
2211
  return (_this$imageFile = this.imageFile()) === null || _this$imageFile === void 0 ? void 0 : _this$imageFile.thumbnailFile();
1942
2212
  },
1943
- title: function title() {
2213
+ title() {
1944
2214
  var _tooltipTexts$this$id, _tooltipTexts$this$id2, _tooltipTexts$this$id3, _tooltipTexts$this$id4, _tooltipTexts$this$id5;
1945
- var tooltipTexts = this.collection.contentElement.configuration.get('tooltipTexts');
2215
+ const tooltipTexts = this.collection.contentElement.configuration.get('tooltipTexts');
1946
2216
  return tooltipTexts === null || tooltipTexts === void 0 ? void 0 : (_tooltipTexts$this$id = tooltipTexts[this.id]) === null || _tooltipTexts$this$id === void 0 ? void 0 : (_tooltipTexts$this$id2 = _tooltipTexts$this$id.title) === null || _tooltipTexts$this$id2 === void 0 ? void 0 : (_tooltipTexts$this$id3 = _tooltipTexts$this$id2[0]) === null || _tooltipTexts$this$id3 === void 0 ? void 0 : (_tooltipTexts$this$id4 = _tooltipTexts$this$id3.children) === null || _tooltipTexts$this$id4 === void 0 ? void 0 : (_tooltipTexts$this$id5 = _tooltipTexts$this$id4[0]) === null || _tooltipTexts$this$id5 === void 0 ? void 0 : _tooltipTexts$this$id5.text;
1947
2217
  },
1948
- imageFile: function imageFile() {
2218
+ imageFile() {
1949
2219
  return this.collection.entry.imageFiles.getByPermaId(this.get('activeImage'));
1950
2220
  },
1951
- highlight: function highlight() {
2221
+ highlight() {
1952
2222
  this.collection.contentElement.postCommand({
1953
2223
  type: 'HIGHLIGHT_AREA',
1954
2224
  index: this.collection.indexOf(this)
1955
2225
  });
1956
2226
  },
1957
- resetHighlight: function resetHighlight() {
2227
+ resetHighlight() {
1958
2228
  this.collection.contentElement.postCommand({
1959
2229
  type: 'RESET_AREA_HIGHLIGHT'
1960
2230
  });
@@ -1965,82 +2235,85 @@ var css$3 = ".AreasListView-module_listContainer__1vyoU {}\n";
1965
2235
  var styles$3 = {"listContainer":"AreasListView-module_listContainer__1vyoU"};
1966
2236
  styleInject(css$3);
1967
2237
 
1968
- var AreasListView = Marionette.Layout.extend({
1969
- template: function template(data) {
1970
- return "\n <div class='".concat(styles$3.listContainer, "'></div>\n <button class=\"").concat(buttonStyles.addButton, "\">\n ").concat(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.areas.add'), "\n </button>\n ");
1971
- },
2238
+ const AreasListView = Marionette.Layout.extend({
2239
+ template: data => `
2240
+ <div class='${styles$3.listContainer}'></div>
2241
+ <button class="${buttonStyles.addButton}">
2242
+ ${I18n.t('pageflow_scrolled.editor.content_elements.hotspots.areas.add')}
2243
+ </button>
2244
+ `,
1972
2245
  regions: cssModulesUtils.ui(styles$3, 'listContainer'),
1973
2246
  events: cssModulesUtils.events(buttonStyles, {
1974
- 'click addButton': function clickAddButton() {
1975
- var _this = this;
1976
- var model = new Area();
2247
+ 'click addButton': function () {
2248
+ const model = new Area();
1977
2249
  EditAreaDialogView.show({
1978
- model: model,
2250
+ model,
1979
2251
  file: this.model.getImageFile('image'),
1980
2252
  portraitFile: this.model.getImageFile('portraitImage'),
1981
- onSave: function onSave() {
1982
- return _this.collection.addWithId(model);
1983
- }
2253
+ onSave: () => this.collection.addWithId(model)
1984
2254
  });
1985
2255
  }
1986
2256
  }),
1987
- onRender: function onRender() {
1988
- var _this2 = this;
2257
+ onRender() {
1989
2258
  this.listContainer.show(new ListView({
1990
2259
  label: I18n.t('pageflow_scrolled.editor.content_elements.hotspots.areas.label'),
1991
2260
  collection: this.collection,
1992
2261
  sortable: true,
1993
2262
  highlight: true,
1994
- onEdit: function onEdit(model) {
1995
- _this2.options.contentElement.postCommand({
2263
+ onEdit: model => {
2264
+ this.options.contentElement.postCommand({
1996
2265
  type: 'SET_ACTIVE_AREA',
1997
- index: _this2.collection.indexOf(model)
2266
+ index: this.collection.indexOf(model)
1998
2267
  });
1999
- editor.navigate("/scrolled/hotspots/".concat(_this2.options.contentElement.id, "/").concat(model.id), {
2268
+ editor.navigate(`/scrolled/hotspots/${this.options.contentElement.id}/${model.id}`, {
2000
2269
  trigger: true
2001
2270
  });
2002
2271
  },
2003
- onRemove: function onRemove(model) {
2272
+ onRemove: model => {
2004
2273
  if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.areas.confirm_delete'))) {
2005
- _this2.collection.remove(model);
2274
+ this.collection.remove(model);
2006
2275
  }
2007
2276
  }
2008
2277
  }));
2009
2278
  }
2010
2279
  });
2011
2280
 
2012
- var AreasCollection = Backbone.Collection.extend({
2281
+ const AreasCollection = Backbone.Collection.extend({
2013
2282
  model: Area,
2014
2283
  comparator: 'position',
2015
- initialize: function initialize(models, options) {
2016
- var _this = this;
2284
+ initialize(models, options) {
2017
2285
  this.entry = options.entry;
2018
2286
  this.contentElement = options.contentElement;
2019
2287
  this.listenTo(this, 'add change sort', this.updateConfiguration);
2020
- this.listenTo(this, 'remove', function () {
2021
- return _this.updateConfiguration({
2022
- pruneTooltips: true
2023
- });
2024
- });
2288
+ this.listenTo(this, 'remove', () => this.updateConfiguration({
2289
+ pruneTooltips: true
2290
+ }));
2025
2291
  },
2026
- updateConfiguration: function updateConfiguration(_ref) {
2027
- var pruneTooltips = _ref.pruneTooltips;
2028
- var updatedAttributes = {
2292
+ updateConfiguration({
2293
+ pruneTooltips
2294
+ }) {
2295
+ let updatedAttributes = {
2029
2296
  areas: this.toJSON()
2030
2297
  };
2031
2298
  if (pruneTooltips) {
2032
- updatedAttributes = _objectSpread2(_objectSpread2(_objectSpread2({}, updatedAttributes), this.getPrunedProperty('tooltipTexts')), this.getPrunedProperty('tooltipLinks'));
2299
+ updatedAttributes = {
2300
+ ...updatedAttributes,
2301
+ ...this.getPrunedProperty('tooltipTexts'),
2302
+ ...this.getPrunedProperty('tooltipLinks')
2303
+ };
2033
2304
  }
2034
2305
  this.contentElement.configuration.set(updatedAttributes);
2035
2306
  },
2036
- getPrunedProperty: function getPrunedProperty(propertyName) {
2037
- return _defineProperty({}, propertyName, _.pick.apply(_, [this.contentElement.configuration.get(propertyName) || {}].concat(_toConsumableArray(this.pluck('id')))));
2307
+ getPrunedProperty(propertyName) {
2308
+ return {
2309
+ [propertyName]: _.pick(this.contentElement.configuration.get(propertyName) || {}, ...this.pluck('id'))
2310
+ };
2038
2311
  },
2039
- addWithId: function addWithId(model) {
2040
- model.set('id', this.length ? Math.max.apply(Math, _toConsumableArray(this.pluck('id'))) + 1 : 1);
2312
+ addWithId(model) {
2313
+ model.set('id', this.length ? Math.max(...this.pluck('id')) + 1 : 1);
2041
2314
  this.add(model);
2042
2315
  },
2043
- saveOrder: function saveOrder() {}
2316
+ saveOrder() {}
2044
2317
  });
2045
2318
  AreasCollection.forContentElement = function (contentElement, entry) {
2046
2319
  return new AreasCollection(contentElement.configuration.get('areas') || [], {
@@ -2049,7 +2322,7 @@ AreasCollection.forContentElement = function (contentElement, entry) {
2049
2322
  });
2050
2323
  };
2051
2324
 
2052
- var SidebarRouter$1 = Marionette.AppRouter.extend({
2325
+ const SidebarRouter$1 = Marionette.AppRouter.extend({
2053
2326
  appRoutes: {
2054
2327
  'scrolled/hotspots/:id/:area_id': 'area',
2055
2328
  'scrolled/hotspots/:id/:area_id/:tab': 'area'
@@ -2060,13 +2333,19 @@ var css$4 = ".AreaInputView-module_button__3LSo- {\n width: 100%;\n}\n";
2060
2333
  var styles$4 = {"button":"AreaInputView-module_button__3LSo-"};
2061
2334
  styleInject(css$4);
2062
2335
 
2063
- var AreaInputView = Marionette.Layout.extend({
2064
- template: function template(data) {
2065
- return "\n <label>\n <span class=\"name\"></span>\n <span class=\"inline_help\"></span>\n </label>\n <button class=\"".concat(buttonStyles.targetButton, " ").concat(styles$4.button, "\">\n ").concat(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.area_input.edit'), "\n </button>\n ");
2066
- },
2336
+ const AreaInputView = Marionette.Layout.extend({
2337
+ template: data => `
2338
+ <label>
2339
+ <span class="name"></span>
2340
+ <span class="inline_help"></span>
2341
+ </label>
2342
+ <button class="${buttonStyles.targetButton} ${styles$4.button}">
2343
+ ${I18n.t('pageflow_scrolled.editor.content_elements.hotspots.area_input.edit')}
2344
+ </button>
2345
+ `,
2067
2346
  mixins: [inputView],
2068
2347
  events: cssModulesUtils.events(buttonStyles, {
2069
- 'click targetButton': function clickTargetButton() {
2348
+ 'click targetButton': function () {
2070
2349
  EditAreaDialogView.show({
2071
2350
  model: this.model,
2072
2351
  file: this.options.file,
@@ -2077,42 +2356,47 @@ var AreaInputView = Marionette.Layout.extend({
2077
2356
  })
2078
2357
  });
2079
2358
 
2080
- var css$5 = ".SidebarEditAreaView-module_view__2AVKF .tabs_view-headers li:nth-child(2) {\n margin-left: 5px;\n}\n\n.SidebarEditAreaView-module_view__2AVKF .tabs_view-headers li:nth-child(2)::before {\n content: \"\\203A\";\n margin-left: -15px;\n margin-right: 10px;\n font-weight: normal;\n}\n";
2359
+ var css$5 = ".SidebarEditAreaView-module_view__2AVKF .tabs_view-tabs > :nth-child(2) {\n margin-left: 5px;\n}\n\n.SidebarEditAreaView-module_view__2AVKF .tabs_view-tabs > :nth-child(2)::before {\n content: \"\\203A\";\n margin-left: -15px;\n margin-right: 10px;\n font-weight: normal;\n}\n";
2081
2360
  var styles$5 = {"view":"SidebarEditAreaView-module_view__2AVKF"};
2082
2361
  styleInject(css$5);
2083
2362
 
2084
- var SidebarEditAreaView = Marionette.Layout.extend({
2085
- template: function template(data) {
2086
- return "\n <a class=\"back\">".concat(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.edit_area.back'), "</a>\n <a class=\"destroy\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.edit_area.destroy'), "</a>\n\n <div class='form_container'></div>\n ");
2363
+ const SidebarEditAreaView = EditConfigurationView.extend({
2364
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.hotspots.edit_area',
2365
+ className: 'edit_configuration_view ' + styles$5.view,
2366
+ containingCollection() {
2367
+ return this.options.collection;
2087
2368
  },
2088
- className: styles$5.view,
2089
- regions: {
2090
- formContainer: '.form_container'
2369
+ getConfigurationModel() {
2370
+ return this.model;
2091
2371
  },
2092
- events: {
2093
- 'click a.back': 'goBack',
2094
- 'click a.destroy': 'destroyLink'
2372
+ defaultTab() {
2373
+ return this.options.tab || (this.options.entry.get('emulation_mode') === 'phone' ? 'portrait' : 'area');
2095
2374
  },
2096
- onRender: function onRender() {
2097
- var _this = this;
2098
- var options = this.options;
2099
- var configurationEditor = new ConfigurationEditorView({
2100
- model: this.model,
2101
- attributeTranslationKeyPrefixes: ['pageflow_scrolled.editor.content_elements.hotspots.edit_area.attributes'],
2102
- tabTranslationKeyPrefix: 'pageflow_scrolled.editor.content_elements.hotspots.edit_area.tabs',
2103
- tab: options.tab || (options.entry.get('emulation_mode') === 'phone' ? 'portrait' : 'area')
2375
+ goBackPath() {
2376
+ return `/scrolled/content_elements/${this.options.contentElement.get('id')}`;
2377
+ },
2378
+ goBack() {
2379
+ this.options.contentElement.postCommand({
2380
+ type: 'SET_ACTIVE_AREA',
2381
+ index: -1
2104
2382
  });
2105
- var file = options.contentElement.configuration.getImageFile('image');
2106
- var portraitFile = options.contentElement.configuration.getImageFile('portraitImage');
2107
- var panZoomEnabled = options.contentElement.configuration.get('enablePanZoom') !== 'never';
2108
- var preserveActiveArea = function preserveActiveArea() {
2109
- return setTimeout(function () {
2110
- return options.contentElement.postCommand({
2111
- type: 'SET_ACTIVE_AREA',
2112
- index: options.collection.indexOf(_this.model)
2113
- });
2114
- }, 200);
2115
- };
2383
+ EditConfigurationView.prototype.goBack.call(this);
2384
+ },
2385
+ getActionsMenuItems() {
2386
+ return [new DestroyAreaMenuItem({}, {
2387
+ collection: this.options.collection,
2388
+ model: this.model
2389
+ })];
2390
+ },
2391
+ configure(configurationEditor) {
2392
+ const options = this.options;
2393
+ const file = options.contentElement.configuration.getImageFile('image');
2394
+ const portraitFile = options.contentElement.configuration.getImageFile('portraitImage');
2395
+ const panZoomEnabled = options.contentElement.configuration.get('enablePanZoom') !== 'never';
2396
+ const preserveActiveArea = () => setTimeout(() => options.contentElement.postCommand({
2397
+ type: 'SET_ACTIVE_AREA',
2398
+ index: options.collection.indexOf(this.model)
2399
+ }), 200);
2116
2400
  if (file && portraitFile) {
2117
2401
  this.previousEmulationMode = options.entry.get('emulation_mode') || 'desktop';
2118
2402
  }
@@ -2122,8 +2406,8 @@ var SidebarEditAreaView = Marionette.Layout.extend({
2122
2406
  preserveActiveArea();
2123
2407
  }
2124
2408
  this.input('area', AreaInputView, {
2125
- file: file,
2126
- portraitFile: portraitFile
2409
+ file,
2410
+ portraitFile
2127
2411
  });
2128
2412
  this.input('activeImage', FileInputView, {
2129
2413
  collection: 'image_files',
@@ -2172,8 +2456,8 @@ var SidebarEditAreaView = Marionette.Layout.extend({
2172
2456
  preserveActiveArea();
2173
2457
  }
2174
2458
  this.input('portraitArea', AreaInputView, {
2175
- file: file,
2176
- portraitFile: portraitFile,
2459
+ file,
2460
+ portraitFile,
2177
2461
  defaultTab: 'portrait'
2178
2462
  });
2179
2463
  this.input('portraitActiveImage', FileInputView, {
@@ -2204,35 +2488,29 @@ var SidebarEditAreaView = Marionette.Layout.extend({
2204
2488
  });
2205
2489
  });
2206
2490
  }
2207
- this.formContainer.show(configurationEditor);
2208
- },
2209
- goBack: function goBack() {
2210
- editor$1.navigate("/scrolled/content_elements/".concat(this.options.contentElement.get('id')), {
2211
- trigger: true
2212
- });
2213
- },
2214
- destroyLink: function destroyLink() {
2215
- if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.hotspots.edit_area.confirm_delete_link'))) {
2216
- this.options.collection.remove(this.model);
2217
- this.goBack();
2218
- }
2491
+ }
2492
+ });
2493
+ const DestroyAreaMenuItem = DestroyMenuItem.extend({
2494
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.hotspots.edit_area',
2495
+ destroyModel() {
2496
+ this.options.collection.remove(this.options.model);
2219
2497
  }
2220
2498
  });
2221
2499
 
2222
- var SidebarController$1 = Marionette.Controller.extend({
2223
- initialize: function initialize(options) {
2500
+ const SidebarController$1 = Marionette.Controller.extend({
2501
+ initialize: function (options) {
2224
2502
  this.entry = options.entry;
2225
2503
  this.region = options.region;
2226
2504
  },
2227
- area: function area(id, areaId, tab) {
2228
- var contentElement = this.entry.contentElements.get(id);
2229
- var areasCollection = AreasCollection.forContentElement(contentElement, this.entry);
2505
+ area: function (id, areaId, tab) {
2506
+ const contentElement = this.entry.contentElements.get(id);
2507
+ const areasCollection = AreasCollection.forContentElement(contentElement, this.entry);
2230
2508
  this.region.show(new SidebarEditAreaView({
2231
2509
  model: areasCollection.get(areaId),
2232
2510
  collection: areasCollection,
2233
2511
  entry: this.entry,
2234
- contentElement: contentElement,
2235
- tab: tab
2512
+ contentElement,
2513
+ tab
2236
2514
  }));
2237
2515
  }
2238
2516
  });
@@ -2248,15 +2526,25 @@ editor.contentElementTypes.register('hotspots', {
2248
2526
  category: 'interactive',
2249
2527
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right', 'backdrop'],
2250
2528
  supportedWidthRange: ['xxs', 'full'],
2251
- editorPath: function editorPath(contentElement) {
2252
- var activeAreaId = contentElement.transientState.get('activeAreaId');
2529
+ supportedCaptions: true,
2530
+ supportedStyles: ['boxShadow', 'outline'],
2531
+ editorPath(contentElement) {
2532
+ const activeAreaId = contentElement.transientState.get('activeAreaId');
2253
2533
  if (activeAreaId) {
2254
- return "/scrolled/hotspots/".concat(contentElement.id, "/").concat(activeAreaId);
2534
+ return `/scrolled/hotspots/${contentElement.id}/${activeAreaId}`;
2255
2535
  }
2256
2536
  },
2257
- configurationEditor: function configurationEditor(_ref) {
2258
- var entry = _ref.entry,
2259
- contentElement = _ref.contentElement;
2537
+ configurationPlace(contentElement, path) {
2538
+ const [propertyName] = path;
2539
+ if (propertyName !== 'areas') {
2540
+ return elementConfigurationPlace(contentElement);
2541
+ }
2542
+ return areaConfigurationPlace(contentElement, path);
2543
+ },
2544
+ configurationEditor({
2545
+ entry,
2546
+ contentElement
2547
+ }) {
2260
2548
  this.tab('general', function () {
2261
2549
  this.input('image', FileInputView, {
2262
2550
  collection: 'image_files',
@@ -2271,7 +2559,7 @@ editor.contentElementTypes.register('hotspots', {
2271
2559
  });
2272
2560
  this.view(AreasListView, {
2273
2561
  configuration: this.model,
2274
- contentElement: contentElement,
2562
+ contentElement,
2275
2563
  collection: AreasCollection.forContentElement(contentElement, entry)
2276
2564
  });
2277
2565
  this.input('invertTooltips', CheckBoxInputView$1);
@@ -2281,25 +2569,26 @@ editor.contentElementTypes.register('hotspots', {
2281
2569
  this.view(SeparatorView$1);
2282
2570
  this.input('enableFullscreen', CheckBoxInputView$1, {
2283
2571
  disabledBinding: ['position', 'width'],
2284
- disabled: function disabled() {
2285
- return contentElement.getWidth() === contentElementWidths.full || contentElement.getPosition() === 'backdrop';
2286
- },
2572
+ disabled: () => contentElement.getWidth() === contentElementWidths.full || contentElement.getPosition() === 'backdrop',
2287
2573
  displayUncheckedIfDisabled: true
2288
2574
  });
2289
2575
  this.group('ContentElementPosition', {
2290
- entry: entry
2576
+ entry
2291
2577
  });
2292
2578
  this.view(SeparatorView$1);
2579
+ this.group('LinkButtonVariant', {
2580
+ entry
2581
+ });
2293
2582
  this.group('ContentElementCaption', {
2294
- entry: entry
2583
+ entry
2295
2584
  });
2296
2585
  this.group('ContentElementInlineFileRightsSettings');
2297
2586
  });
2298
2587
  }
2299
2588
  });
2300
2589
  editor.registerFileSelectionHandler('hotspotsArea', function (options) {
2301
- var contentElement = options.entry.contentElements.get(options.contentElementId);
2302
- var areas = AreasCollection.forContentElement(contentElement, options.entry);
2590
+ const contentElement = options.entry.contentElements.get(options.contentElementId);
2591
+ const areas = AreasCollection.forContentElement(contentElement, options.entry);
2303
2592
  this.call = function (file) {
2304
2593
  areas.get(options.id).setReference(options.attributeName, file);
2305
2594
  };
@@ -2308,16 +2597,57 @@ editor.registerFileSelectionHandler('hotspotsArea', function (options) {
2308
2597
  };
2309
2598
  });
2310
2599
 
2600
+ // The editor path of the element points at the active area, which
2601
+ // would send the sidebar back to an area the property is not in.
2602
+ function elementConfigurationPlace(contentElement) {
2603
+ return {
2604
+ select() {
2605
+ contentElement.postCommand({
2606
+ type: 'SET_ACTIVE_AREA',
2607
+ index: -1
2608
+ });
2609
+ contentElement.select();
2610
+ }
2611
+ };
2612
+ }
2613
+ function areaConfigurationPlace(contentElement, [, index, propertyName]) {
2614
+ const area = contentElement.configuration.get('areas')[index];
2615
+ const tab = propertyName.startsWith('portrait') ? 'portrait' : 'area';
2616
+ return {
2617
+ label: areaAttributeLabel(propertyName),
2618
+ select() {
2619
+ contentElement.postCommand({
2620
+ type: 'SET_ACTIVE_AREA',
2621
+ index: Number(index)
2622
+ });
2623
+ contentElement.select({
2624
+ navigate: false
2625
+ });
2626
+ editor.navigate(`/scrolled/hotspots/${contentElement.id}/${area.id}/${tab}`, {
2627
+ trigger: true
2628
+ });
2629
+ }
2630
+ };
2631
+ }
2632
+ function areaAttributeLabel(propertyName) {
2633
+ return I18n.t(`${propertyName}.label`, {
2634
+ scope: 'pageflow_scrolled.editor.content_elements.hotspots.edit_area.attributes'
2635
+ });
2636
+ }
2637
+
2311
2638
  var img$e = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512'%3e%3c!--! Font Awesome Pro 6.1.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons%2c Inc. --%3e%3cpath fill='white' d='M578.2 66.06C409.8 116.6 230.2 116.6 61.8 66.06C31 56.82 0 79.88 0 112v319.9c0 32.15 30.1 55.21 61.79 45.97c168.4-50.53 347.1-50.53 516.4-.002C608.1 487.2 640 464.1 640 431.1V112C640 79.88 609 56.82 578.2 66.06zM128 224C110.3 224 96 209.7 96 192s14.33-32 32-32c17.68 0 32 14.33 32 32S145.7 224 128 224zM474.3 388.6C423.4 380.3 371.8 376 320 376c-50.45 0-100.7 4.043-150.3 11.93c-14.14 2.246-24.11-13.19-15.78-24.84l49.18-68.56C206.1 290.4 210.9 288 216 288s9.916 2.441 12.93 6.574l32.46 44.51l93.3-139.1C357.7 194.7 362.7 192 368 192s10.35 2.672 13.31 7.125l109.1 165.1C498.1 375.9 488.1 390.8 474.3 388.6z'/%3e%3c/svg%3e";
2312
2639
 
2313
- var aspectRatios = ['wide', 'narrow', 'square', 'portrait'];
2640
+ const aspectRatios = ['wide', 'narrow', 'square', 'portrait'];
2314
2641
  editor.contentElementTypes.register('vrImage', {
2315
2642
  pictogram: img$e,
2316
2643
  category: 'interactive',
2317
2644
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right', 'backdrop'],
2318
2645
  supportedWidthRange: ['xxs', 'full'],
2319
- configurationEditor: function configurationEditor(_ref) {
2320
- var entry = _ref.entry;
2646
+ supportedCaptions: true,
2647
+ supportedStyles: ['boxShadow', 'outline'],
2648
+ configurationEditor({
2649
+ entry
2650
+ }) {
2321
2651
  this.tab('general', function () {
2322
2652
  this.input('image', FileInputView, {
2323
2653
  collection: 'image_files',
@@ -2348,18 +2678,18 @@ editor.contentElementTypes.register('vrImage', {
2348
2678
  });
2349
2679
  this.view(SeparatorView$1);
2350
2680
  this.group('ContentElementPosition', {
2351
- entry: entry
2681
+ entry
2352
2682
  });
2353
2683
  this.view(SeparatorView$1);
2354
2684
  this.group('ContentElementCaption', {
2355
- entry: entry
2685
+ entry
2356
2686
  });
2357
2687
  this.group('ContentElementInlineFileRightsSettings');
2358
2688
  });
2359
2689
  }
2360
2690
  });
2361
2691
  editor.fileTypes.modify('image_files', {
2362
- configurationEditorInputs: function configurationEditorInputs(model) {
2692
+ configurationEditorInputs(model) {
2363
2693
  var values = ['equirectangular_mono', 'equirectangular_stereo'];
2364
2694
  return [{
2365
2695
  name: 'projection',
@@ -2376,7 +2706,7 @@ editor.fileTypes.modify('image_files', {
2376
2706
  }],
2377
2707
  filters: [{
2378
2708
  name: 'with_projection',
2379
- matches: function matches(file) {
2709
+ matches: function (file) {
2380
2710
  return !!file.configuration.get('projection');
2381
2711
  }
2382
2712
  }]
@@ -2384,28 +2714,28 @@ editor.fileTypes.modify('image_files', {
2384
2714
 
2385
2715
  var img$f = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512'%3e%3c!--! Font Awesome Pro 6.1.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons%2c Inc. --%3e%3cpath fill='white' d='M414.8 40.79L286.8 488.8C281.9 505.8 264.2 515.6 247.2 510.8C230.2 505.9 220.4 488.2 225.2 471.2L353.2 23.21C358.1 6.216 375.8-3.624 392.8 1.232C409.8 6.087 419.6 23.8 414.8 40.79H414.8zM518.6 121.4L630.6 233.4C643.1 245.9 643.1 266.1 630.6 278.6L518.6 390.6C506.1 403.1 485.9 403.1 473.4 390.6C460.9 378.1 460.9 357.9 473.4 345.4L562.7 256L473.4 166.6C460.9 154.1 460.9 133.9 473.4 121.4C485.9 108.9 506.1 108.9 518.6 121.4V121.4zM166.6 166.6L77.25 256L166.6 345.4C179.1 357.9 179.1 378.1 166.6 390.6C154.1 403.1 133.9 403.1 121.4 390.6L9.372 278.6C-3.124 266.1-3.124 245.9 9.372 233.4L121.4 121.4C133.9 108.9 154.1 108.9 166.6 121.4C179.1 133.9 179.1 154.1 166.6 166.6V166.6z'/%3e%3c/svg%3e";
2386
2716
 
2387
- var aspectRatios$1 = ['wide', 'narrow', 'square', 'portrait'];
2717
+ const aspectRatios$1 = ['wide', 'narrow', 'square', 'portrait'];
2388
2718
  editor.contentElementTypes.register('iframeEmbed', {
2389
2719
  pictogram: img$f,
2390
2720
  category: 'interactive',
2391
2721
  featureName: 'iframe_embed_content_element',
2392
2722
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2393
2723
  supportedWidthRange: ['xxs', 'full'],
2394
- configurationEditor: function configurationEditor(_ref) {
2395
- var entry = _ref.entry;
2724
+ supportedCaptions: true,
2725
+ supportedStyles: ['boxShadow', 'outline'],
2726
+ configurationEditor({
2727
+ entry
2728
+ }) {
2396
2729
  this.tab('general', function () {
2397
- this.input('source', TextInputView);
2730
+ this.input('source', TextInputView, {
2731
+ maxLength: 2000
2732
+ });
2398
2733
  this.input('requireConsent', CheckBoxInputView);
2399
2734
  this.view(InfoBoxView, {
2400
2735
  level: 'error',
2401
2736
  text: I18n.t('pageflow_scrolled.editor.content_elements.iframeEmbed.help_texts.missingConsentVendor'),
2402
2737
  visibleBinding: ['source', 'requireConsent'],
2403
- visible: function visible(_ref2) {
2404
- var _ref3 = _slicedToArray(_ref2, 2),
2405
- source = _ref3[0],
2406
- requireConsent = _ref3[1];
2407
- return source && requireConsent && !entry.consentVendors.fromUrl(source);
2408
- }
2738
+ visible: ([source, requireConsent]) => source && requireConsent && !entry.consentVendors.fromUrl(source)
2409
2739
  });
2410
2740
  this.input('title', TextInputView);
2411
2741
  this.input('aspectRatio', SelectInputView, {
@@ -2428,11 +2758,11 @@ editor.contentElementTypes.register('iframeEmbed', {
2428
2758
  values: ['p100', 'p75', 'p50', 'p33']
2429
2759
  });
2430
2760
  this.group('ContentElementPosition', {
2431
- entry: entry
2761
+ entry
2432
2762
  });
2433
2763
  this.view(SeparatorView);
2434
2764
  this.group('ContentElementCaption', {
2435
- entry: entry
2765
+ entry
2436
2766
  });
2437
2767
  });
2438
2768
  }
@@ -2442,76 +2772,80 @@ var css$6 = ".ItemsListView-module_listContainer__2XDCy {\n}\n";
2442
2772
  var styles$6 = {"listContainer":"ItemsListView-module_listContainer__2XDCy"};
2443
2773
  styleInject(css$6);
2444
2774
 
2445
- var ItemsListView = Marionette.Layout.extend({
2446
- template: function template(data) {
2447
- return "\n <div class='".concat(styles$6.listContainer, "'></div>\n <button class=\"").concat(buttonStyles.addButton, "\">\n ").concat(I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.items.add'), "\n </button>\n ");
2448
- },
2775
+ const ItemsListView = Marionette.Layout.extend({
2776
+ template: data => `
2777
+ <div class='${styles$6.listContainer}'></div>
2778
+ <button class="${buttonStyles.addButton}">
2779
+ ${I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.items.add')}
2780
+ </button>
2781
+ `,
2449
2782
  regions: cssModulesUtils.ui(styles$6, 'listContainer'),
2450
2783
  events: cssModulesUtils.events(buttonStyles, {
2451
- 'click addButton': function clickAddButton() {
2784
+ 'click addButton': function () {
2452
2785
  this.collection.selectImage();
2453
2786
  }
2454
2787
  }),
2455
- onRender: function onRender() {
2456
- var _this = this;
2788
+ onRender() {
2457
2789
  this.listContainer.show(new ListView({
2458
2790
  label: I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.items.label'),
2459
2791
  collection: this.collection,
2460
2792
  sortable: true,
2461
- onEdit: function onEdit(model) {
2462
- editor.navigate("/scrolled/imageGalleries/".concat(_this.options.contentElement.id, "/").concat(model.id), {
2793
+ onEdit: model => {
2794
+ this.options.contentElement.postCommand({
2795
+ type: 'SET_CURRENT_ITEM',
2796
+ index: this.collection.indexOf(model)
2797
+ });
2798
+ editor.navigate(`/scrolled/imageGalleries/${this.options.contentElement.id}/${model.id}`, {
2463
2799
  trigger: true
2464
2800
  });
2465
2801
  },
2466
- onRemove: function onRemove(model) {
2467
- return _this.collection.remove(model);
2468
- }
2802
+ onRemove: model => this.collection.remove(model)
2469
2803
  }));
2470
2804
  }
2471
2805
  });
2472
2806
 
2473
- var Item = Backbone.Model.extend({
2807
+ const Item = Backbone.Model.extend({
2474
2808
  mixins: [transientReferences],
2475
- thumbnailFile: function thumbnailFile() {
2809
+ thumbnailFile() {
2476
2810
  var _this$imageFile;
2477
2811
  return (_this$imageFile = this.imageFile()) === null || _this$imageFile === void 0 ? void 0 : _this$imageFile.thumbnailFile();
2478
2812
  },
2479
- title: function title() {
2813
+ title() {
2480
2814
  var _this$imageFile2;
2481
2815
  return (_this$imageFile2 = this.imageFile()) === null || _this$imageFile2 === void 0 ? void 0 : _this$imageFile2.title();
2482
2816
  },
2483
- imageFile: function imageFile() {
2817
+ imageFile() {
2484
2818
  return this.collection.entry.imageFiles.getByPermaId(this.get('image'));
2485
2819
  }
2486
2820
  });
2487
2821
 
2488
- var ItemsCollection = Backbone.Collection.extend({
2822
+ const ItemsCollection = Backbone.Collection.extend({
2489
2823
  model: Item,
2490
2824
  comparator: 'position',
2491
- initialize: function initialize(models, options) {
2825
+ initialize(models, options) {
2492
2826
  this.entry = options.entry;
2493
2827
  this.contentElement = options.contentElement;
2494
2828
  this.listenTo(this, 'add change remove sort', this.updateConfiguration);
2495
2829
  this.listenTo(this, 'remove', this.pruneCaptions);
2496
2830
  },
2497
- updateConfiguration: function updateConfiguration() {
2831
+ updateConfiguration() {
2498
2832
  this.contentElement.configuration.set('items', this.toJSON());
2499
2833
  },
2500
- pruneCaptions: function pruneCaptions() {
2501
- this.contentElement.configuration.set('captions', _.pick.apply(_, [this.contentElement.configuration.get('captions') || {}].concat(_toConsumableArray(this.pluck('id')))));
2834
+ pruneCaptions() {
2835
+ this.contentElement.configuration.set('captions', _.pick(this.contentElement.configuration.get('captions') || {}, ...this.pluck('id')));
2502
2836
  },
2503
- selectImage: function selectImage() {
2837
+ selectImage() {
2504
2838
  editor$1.selectFile('image_files', 'newImageGalleryItem', {
2505
2839
  id: this.contentElement.id
2506
2840
  });
2507
2841
  },
2508
- addWithId: function addWithId(imageFile) {
2842
+ addWithId(imageFile) {
2509
2843
  this.add({
2510
- id: this.length ? Math.max.apply(Math, _toConsumableArray(this.pluck('id'))) + 1 : 1,
2844
+ id: this.length ? Math.max(...this.pluck('id')) + 1 : 1,
2511
2845
  image: imageFile.get('perma_id')
2512
2846
  });
2513
2847
  },
2514
- saveOrder: function saveOrder() {}
2848
+ saveOrder() {}
2515
2849
  });
2516
2850
  ItemsCollection.forContentElement = function (contentElement, entry) {
2517
2851
  return new ItemsCollection(contentElement.configuration.get('items') || [], {
@@ -2519,8 +2853,8 @@ ItemsCollection.forContentElement = function (contentElement, entry) {
2519
2853
  contentElement: contentElement
2520
2854
  });
2521
2855
  };
2522
- var FileSelectionHandler = function FileSelectionHandler(options) {
2523
- var contentElement = options.entry.contentElements.get(options.id);
2856
+ const FileSelectionHandler = function (options) {
2857
+ const contentElement = options.entry.contentElements.get(options.id);
2524
2858
  this.call = function (file) {
2525
2859
  ItemsCollection.forContentElement(contentElement).addWithId(file);
2526
2860
  };
@@ -2530,36 +2864,37 @@ var FileSelectionHandler = function FileSelectionHandler(options) {
2530
2864
  };
2531
2865
  editor$1.registerFileSelectionHandler('newImageGalleryItem', FileSelectionHandler);
2532
2866
 
2533
- var SidebarRouter$2 = Marionette.AppRouter.extend({
2867
+ const SidebarRouter$2 = Marionette.AppRouter.extend({
2534
2868
  appRoutes: {
2535
2869
  'scrolled/imageGalleries/:id/:item_id': 'item'
2536
2870
  }
2537
2871
  });
2538
2872
 
2539
- var SidebarEditItemView = Marionette.Layout.extend({
2540
- template: function template(data) {
2541
- return "\n <a class=\"back\">".concat(I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.edit_item.back'), "</a>\n <a class=\"destroy\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.edit_item.destroy'), "</a>\n\n <div class='form_container'></div>\n ");
2873
+ const SidebarEditItemView = EditConfigurationView.extend({
2874
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.imageGallery.edit_item',
2875
+ containingCollection() {
2876
+ return this.options.collection;
2542
2877
  },
2543
- regions: {
2544
- formContainer: '.form_container'
2878
+ getConfigurationModel() {
2879
+ return this.model;
2545
2880
  },
2546
- events: {
2547
- 'click a.back': 'goBack',
2548
- 'click a.destroy': 'destroyLink'
2881
+ goBackPath() {
2882
+ return `/scrolled/content_elements/${this.options.contentElement.get('id')}`;
2549
2883
  },
2550
- onRender: function onRender() {
2551
- var options = this.options;
2552
- var configurationEditor = new ConfigurationEditorView({
2553
- model: this.model,
2554
- attributeTranslationKeyPrefixes: ['pageflow_scrolled.editor.content_elements.imageGallery.edit_item.attributes'],
2555
- tabTranslationKeyPrefix: 'pageflow_scrolled.editor.content_elements.imageGallery.edit_item.tabs'
2556
- });
2884
+ getActionsMenuItems() {
2885
+ return [new DestroyItemMenuItem({}, {
2886
+ collection: this.options.collection,
2887
+ model: this.model
2888
+ })];
2889
+ },
2890
+ configure(configurationEditor) {
2891
+ const contentElement = this.options.contentElement;
2557
2892
  configurationEditor.tab('item', function () {
2558
2893
  this.input('image', FileInputView, {
2559
2894
  collection: 'image_files',
2560
2895
  fileSelectionHandler: 'imageGalleryItem',
2561
2896
  fileSelectionHandlerOptions: {
2562
- contentElementId: options.contentElement.get('id')
2897
+ contentElementId: contentElement.get('id')
2563
2898
  },
2564
2899
  positioning: false
2565
2900
  });
@@ -2567,39 +2902,33 @@ var SidebarEditItemView = Marionette.Layout.extend({
2567
2902
  collection: 'image_files',
2568
2903
  fileSelectionHandler: 'imageGalleryItem',
2569
2904
  fileSelectionHandlerOptions: {
2570
- contentElementId: options.contentElement.get('id')
2905
+ contentElementId: contentElement.get('id')
2571
2906
  },
2572
2907
  positioning: false
2573
2908
  });
2574
2909
  });
2575
- this.formContainer.show(configurationEditor);
2576
- },
2577
- goBack: function goBack() {
2578
- editor$1.navigate("/scrolled/content_elements/".concat(this.options.contentElement.get('id')), {
2579
- trigger: true
2580
- });
2581
- },
2582
- destroyLink: function destroyLink() {
2583
- if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.imageGallery.edit_item.confirm_delete_link'))) {
2584
- this.options.collection.remove(this.model);
2585
- this.goBack();
2586
- }
2910
+ }
2911
+ });
2912
+ const DestroyItemMenuItem = DestroyMenuItem.extend({
2913
+ translationKeyPrefix: 'pageflow_scrolled.editor.content_elements.imageGallery.edit_item',
2914
+ destroyModel() {
2915
+ this.options.collection.remove(this.options.model);
2587
2916
  }
2588
2917
  });
2589
2918
 
2590
- var SidebarController$2 = Marionette.Controller.extend({
2591
- initialize: function initialize(options) {
2919
+ const SidebarController$2 = Marionette.Controller.extend({
2920
+ initialize: function (options) {
2592
2921
  this.entry = options.entry;
2593
2922
  this.region = options.region;
2594
2923
  },
2595
- item: function item(id, itemId) {
2596
- var contentElement = this.entry.contentElements.get(id);
2597
- var itemsCollection = ItemsCollection.forContentElement(contentElement, this.entry);
2924
+ item: function (id, itemId) {
2925
+ const contentElement = this.entry.contentElements.get(id);
2926
+ const itemsCollection = ItemsCollection.forContentElement(contentElement, this.entry);
2598
2927
  this.region.show(new SidebarEditItemView({
2599
2928
  model: itemsCollection.get(itemId),
2600
2929
  collection: itemsCollection,
2601
2930
  entry: this.entry,
2602
- contentElement: contentElement
2931
+ contentElement
2603
2932
  }));
2604
2933
  }
2605
2934
  });
@@ -2615,12 +2944,39 @@ editor.contentElementTypes.register('imageGallery', {
2615
2944
  category: 'media',
2616
2945
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2617
2946
  supportedWidthRange: ['xxs', 'full'],
2618
- configurationEditor: function configurationEditor(_ref) {
2619
- var entry = _ref.entry,
2620
- contentElement = _ref.contentElement;
2947
+ supportedCaptions: {
2948
+ disableWhenNoCaption: false
2949
+ },
2950
+ supportedStyles: ['boxShadow', 'outline'],
2951
+ configurationPlace(contentElement, path) {
2952
+ const [propertyName, index, itemProperty] = path;
2953
+ if (propertyName !== 'items') {
2954
+ return;
2955
+ }
2956
+ const item = contentElement.configuration.get('items')[index];
2957
+ return {
2958
+ label: attributeLabel$1(itemProperty),
2959
+ select() {
2960
+ contentElement.postCommand({
2961
+ type: 'SET_CURRENT_ITEM',
2962
+ index: Number(index)
2963
+ });
2964
+ contentElement.select({
2965
+ navigate: false
2966
+ });
2967
+ editor.navigate(`/scrolled/imageGalleries/${contentElement.id}/${item.id}`, {
2968
+ trigger: true
2969
+ });
2970
+ }
2971
+ };
2972
+ },
2973
+ configurationEditor({
2974
+ entry,
2975
+ contentElement
2976
+ }) {
2621
2977
  this.tab('general', function () {
2622
2978
  this.view(ItemsListView, {
2623
- contentElement: contentElement,
2979
+ contentElement,
2624
2980
  collection: ItemsCollection.forContentElement(this.model.parent, entry)
2625
2981
  });
2626
2982
  this.input('displayPeeks', CheckBoxInputView$1, {
@@ -2629,21 +2985,19 @@ editor.contentElementTypes.register('imageGallery', {
2629
2985
  this.input('displayPaginationIndicator', CheckBoxInputView$1);
2630
2986
  this.input('enableFullscreenOnDesktop', CheckBoxInputView$1, {
2631
2987
  disabledBinding: ['position', 'width'],
2632
- disabled: function disabled() {
2633
- return contentElement.getWidth() === contentElementWidths.full;
2634
- },
2988
+ disabled: () => contentElement.getWidth() === contentElementWidths.full,
2635
2989
  displayUncheckedIfDisabled: true
2636
2990
  });
2637
2991
  this.group('ContentElementPosition', {
2638
- entry: entry
2992
+ entry
2639
2993
  });
2640
2994
  this.view(SeparatorView$1);
2641
2995
  this.group('ContentElementCaption', {
2642
- entry: entry,
2996
+ entry,
2643
2997
  disableWhenNoCaption: false
2644
2998
  });
2645
2999
  this.group('ContentElementInlineFileRightsSettings', {
2646
- entry: entry,
3000
+ entry,
2647
3001
  disableWhenNoFileRights: false
2648
3002
  });
2649
3003
  });
@@ -2653,8 +3007,8 @@ editor.contentElementTypes.register('imageGallery', {
2653
3007
  }
2654
3008
  });
2655
3009
  editor.registerFileSelectionHandler('imageGalleryItem', function (options) {
2656
- var contentElement = options.entry.contentElements.get(options.contentElementId);
2657
- var items = ItemsCollection.forContentElement(contentElement, options.entry);
3010
+ const contentElement = options.entry.contentElements.get(options.contentElementId);
3011
+ const items = ItemsCollection.forContentElement(contentElement, options.entry);
2658
3012
  this.call = function (file) {
2659
3013
  items.get(options.id).setReference(options.attributeName, file);
2660
3014
  };
@@ -2662,15 +3016,350 @@ editor.registerFileSelectionHandler('imageGalleryItem', function (options) {
2662
3016
  return '/scrolled/imageGalleries/' + contentElement.id + '/' + options.id;
2663
3017
  };
2664
3018
  });
3019
+ function attributeLabel$1(propertyName) {
3020
+ return I18n.t(`${propertyName}.label`, {
3021
+ scope: 'pageflow_scrolled.editor.content_elements.imageGallery.edit_item.attributes'
3022
+ });
3023
+ }
2665
3024
 
2666
- var img$h = "data:image/svg+xml,%3csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e %3cpath fill='white' d='M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z'/%3e%3c/svg%3e";
3025
+ const LottieFile = UploadableFile.extend({
3026
+ isPositionable: function () {
3027
+ return this.isReady();
3028
+ }
3029
+ });
2667
3030
 
2668
- editor.contentElementTypes.register('twitterEmbed', {
3031
+ // Prevent the player from fetching its WebAssembly module from a CDN.
3032
+ // Frontend and editor run in separate bundles and thus each need to
3033
+ // point the player at the module emitted by their own build.
3034
+ DotLottie.setWasmUrl(wasmUrl);
3035
+
3036
+ // Base class for views which play a lottie file. Sub classes render a
3037
+ // canvas, return the options the player shall be created with from
3038
+ // `playerOptions` and use `onAnimationLoad` for everything that
3039
+ // requires the player to have read the file.
3040
+ const LottieFilePlayerView = Marionette.ItemView.extend({
3041
+ ui: {
3042
+ canvas: 'canvas'
3043
+ },
3044
+ onRender: function () {
3045
+ // Sub classes size themselves based on dimensions which only the
3046
+ // animation provides. The canvas stays invisible until the player
3047
+ // has read them. Taking it out of the layout instead would let the
3048
+ // surrounding box collapse and jump back open.
3049
+ this.$el.css('visibility', 'hidden');
3050
+ this.player = new DotLottie({
3051
+ canvas: this.ui.canvas[0],
3052
+ src: this.model.get('original_url'),
3053
+ renderConfig: {
3054
+ autoResize: true
3055
+ },
3056
+ ...this.playerOptions()
3057
+ });
3058
+ this.player.addEventListener('load', () => {
3059
+ this.onAnimationLoad();
3060
+
3061
+ // The player has already drawn a frame into a canvas of the size
3062
+ // the view had before. It only notices the new size via a resize
3063
+ // observer, which fires too late to keep the frame from being
3064
+ // stretched into the new box.
3065
+ this.player.resize();
3066
+ this.$el.css('visibility', '');
3067
+ });
3068
+ },
3069
+ playerOptions: function () {
3070
+ return {};
3071
+ },
3072
+ onAnimationLoad: function () {},
3073
+ onClose: function () {
3074
+ this.player.destroy();
3075
+ }
3076
+ });
3077
+
3078
+ var css$7 = ".LottieFilePositioningView-module_cover__3ZKEB {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* A max height would squash the canvas instead of scaling it down,\n since the aspect ratio only determines the height before it is\n clamped. Limiting the width covers both directions. */\n.LottieFilePositioningView-module_contain__2UeDA {\n display: block;\n width: var(--positioning-width, 100%);\n max-width: min(var(--positioning-max-width, 100%),\n var(--positioning-max-height, 100vh) *\n var(--positioning-aspect-ratio, 1));\n aspect-ratio: var(--positioning-aspect-ratio, 1);\n}\n\n.LottieFilePositioningView-module_canvas__3OxWg {\n display: block;\n width: 100%;\n height: 100%;\n}\n";
3079
+ var styles$7 = {"cover":"LottieFilePositioningView-module_cover__3ZKEB","contain":"LottieFilePositioningView-module_contain__2UeDA","canvas":"LottieFilePositioningView-module_canvas__3OxWg"};
3080
+ styleInject(css$7);
3081
+
3082
+ const LottieFilePositioningView = LottieFilePlayerView.extend({
3083
+ template: () => `<canvas class="${styles$7.canvas}"></canvas>`,
3084
+ className: function () {
3085
+ return styles$7[this.options.fit];
3086
+ },
3087
+ playerOptions: function () {
3088
+ return {
3089
+ autoplay: true,
3090
+ loop: true,
3091
+ layout: this.layout()
3092
+ };
3093
+ },
3094
+ setPosition: function (x, y) {
3095
+ this.align = [x / 100, y / 100];
3096
+ this.player.setLayout(this.layout());
3097
+ },
3098
+ // The player ignores layout changes as long as it is still reading
3099
+ // the file.
3100
+ onAnimationLoad: function () {
3101
+ this.player.setLayout(this.layout());
3102
+ this.applyDimensions();
3103
+ },
3104
+ layout: function () {
3105
+ return {
3106
+ fit: this.options.fit,
3107
+ align: this.align
3108
+ };
3109
+ },
3110
+ // Unlike images and videos, lottie files have no dimensions stored on
3111
+ // the server. The box can thus only be sized once the player has read
3112
+ // them from the file.
3113
+ applyDimensions: function () {
3114
+ var size = this.player.animationSize();
3115
+ if (size.width && size.height) {
3116
+ this.el.style.setProperty('--positioning-aspect-ratio', `${size.width / size.height}`);
3117
+ this.el.style.setProperty('--positioning-width', `${size.width}px`);
3118
+ }
3119
+ }
3120
+ });
3121
+
3122
+ var css$8 = "/* Scaled down to whatever height the overlay has left, just like the\n image and video previews. The player keeps the animation centered\n inside the canvas, so a clamped height only adds transparent space\n left and right. */\n.LottieFilePreviewView-module_canvas__h1U-D {\n display: block;\n width: 100%;\n max-width: var(--preview-width, 100%);\n max-height: var(--preview-max-height, none);\n margin: 0 auto;\n aspect-ratio: var(--preview-aspect-ratio, 1);\n}\n";
3123
+ var styles$8 = {"canvas":"LottieFilePreviewView-module_canvas__h1U-D"};
3124
+ styleInject(css$8);
3125
+
3126
+ const LottieFilePreviewView = LottieFilePlayerView.extend({
3127
+ template: () => `<canvas class="${styles$8.canvas}"></canvas>`,
3128
+ className: 'file_preview',
3129
+ playerOptions: function () {
3130
+ return {
3131
+ autoplay: true,
3132
+ loop: true
3133
+ };
3134
+ },
3135
+ // Unlike images and videos, lottie files have no dimensions stored on
3136
+ // the server. The box can thus only be sized once the player has read
3137
+ // them from the file.
3138
+ onAnimationLoad: function () {
3139
+ var size = this.player.animationSize();
3140
+ if (size.width && size.height) {
3141
+ this.ui.canvas[0].style.setProperty('--preview-aspect-ratio', `${size.width} / ${size.height}`);
3142
+ this.ui.canvas[0].style.setProperty('--preview-width', `${size.width}px`);
3143
+ }
3144
+ }
3145
+ });
3146
+
3147
+ var css$9 = ".LottieFileThumbnailView-module_thumbnail__2joie,\n.LottieFileThumbnailView-module_canvas__1Aby1 {\n display: block;\n width: 100%;\n height: 100%;\n}\n";
3148
+ var styles$9 = {"thumbnail":"LottieFileThumbnailView-module_thumbnail__2joie","canvas":"LottieFileThumbnailView-module_canvas__1Aby1"};
3149
+ styleInject(css$9);
3150
+
3151
+ const LottieFileThumbnailView = LottieFilePlayerView.extend({
3152
+ template: () => `<canvas class="${styles$9.canvas}"></canvas>`,
3153
+ className: styles$9.thumbnail,
3154
+ playerOptions: function () {
3155
+ return {
3156
+ autoplay: false,
3157
+ layout: {
3158
+ fit: 'cover'
3159
+ }
3160
+ };
3161
+ },
3162
+ // Animations commonly build up their scene over time, which would
3163
+ // leave the thumbnail close to blank on the first frame the player
3164
+ // draws once it has loaded the file.
3165
+ onAnimationLoad: function () {
3166
+ this.player.setFrame(this.player.totalFrames - 1);
3167
+ }
3168
+ });
3169
+
3170
+ var img$h = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='white' d='M400 176a72 72 0 1 1-144 0 72 72 0 0 1 144 0zM240 288a44 44 0 1 1-88 0 44 44 0 0 1 88 0zM136 384a28 28 0 1 1-56 0 28 28 0 0 1 56 0zM72 448a16 16 0 1 1-32 0 16 16 0 0 1 32 0z'/%3e%3c/svg%3e";
3171
+
3172
+ editor.fileTypes.register('lottie_files', {
3173
+ model: LottieFile,
3174
+ positioningView: LottieFilePositioningView,
3175
+ previewView: LottieFilePreviewView,
3176
+ thumbnailView: LottieFileThumbnailView,
3177
+ metaDataAttributes: [altMetaDataAttribute],
3178
+ configurationEditorInputs: [altConfigurationEditorInput],
3179
+ // Browsers derive the content type of uploads from the file
3180
+ // extension. Since dotLottie is missing from their mappings, uploads
3181
+ // have an empty content type and matching by name is the only option.
3182
+ matchUpload: upload => /\.lottie$/i.test(upload.name)
3183
+ });
3184
+ const playbackModes = ['loop', 'playOnce', 'scroll'];
3185
+ const startAnimationTriggers = ['onActivate', 'onVisible'];
3186
+ const scrollRanges = ['cover', 'contain', 'inFocus', 'entry'];
3187
+ const pinnedPositions = ['sticky', 'standAlone'];
3188
+ const scrollRangeValuesKey = 'pageflow_scrolled.editor.content_elements.lottieAnimation.attributes.scrollRange.values';
3189
+ const pinnedScrollRangeKeys = ['cover', 'contain', 'inFocusWhenPinned', 'entry'].map(name => `${scrollRangeValuesKey}.${name}`);
3190
+ editor.contentElementTypes.register('lottieAnimation', {
2669
3191
  pictogram: img$h,
2670
3192
  category: 'media',
3193
+ featureName: 'lottie_animation_content_element',
3194
+ supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
3195
+ supportedWidthRange: ['xxs', 'full'],
3196
+ supportedCaptions: true,
3197
+ supportedStyles: ['boxShadow', 'outline'],
3198
+ defaultConfig: {
3199
+ playbackMode: 'loop'
3200
+ },
3201
+ defaultsInputs() {
3202
+ this.input('playbackMode', SelectInputView, {
3203
+ values: playbackModes
3204
+ });
3205
+ },
3206
+ configurationEditor({
3207
+ entry,
3208
+ contentElement
3209
+ }) {
3210
+ this.tab('general', function () {
3211
+ this.input('id', FileInputView, {
3212
+ collection: 'lottie_files',
3213
+ fileSelectionHandler: 'contentElementConfiguration',
3214
+ positioning: imageModifiers => !!processImageModifiers(imageModifiers).aspectRatio,
3215
+ positioningBinding: 'imageModifiers',
3216
+ positioningOptions: () => {
3217
+ const {
3218
+ aspectRatio
3219
+ } = processImageModifiers(this.model.get('imageModifiers'));
3220
+ return {
3221
+ preview: aspectRatio && 1 / entry.getAspectRatio(aspectRatio)
3222
+ };
3223
+ },
3224
+ dropDownMenuItems: [InlineFileRightsMenuItem]
3225
+ });
3226
+ this.input('imageModifiers', ImageModifierListInputView, {
3227
+ entry,
3228
+ visibleBinding: 'id',
3229
+ visible: () => this.model.getReference('id', 'lottie_files')
3230
+ });
3231
+ this.input('playbackMode', SelectInputView, {
3232
+ values: playbackModes
3233
+ });
3234
+ this.input('startAnimationTrigger', PlaybackStartSelectInputView, {
3235
+ values: startAnimationTriggers,
3236
+ ...illustrationOptions(contentElement),
3237
+ visibleBinding: 'playbackMode',
3238
+ visible: playbackMode => playbackMode === 'playOnce'
3239
+ });
3240
+ // Elements that stay in place while scrolling name the inFocus
3241
+ // range after that phase instead of after the center of the
3242
+ // viewport. Since the texts of a select cannot depend on other
3243
+ // attributes, there is one input per wording.
3244
+ this.input('scrollRange', ScrollRangeSelectInputView, {
3245
+ values: scrollRanges,
3246
+ ...illustrationOptions(contentElement),
3247
+ visibleBinding: ['playbackMode', 'position'],
3248
+ visible: ([playbackMode]) => playbackMode === 'scroll' && !staysInPlace(contentElement)
3249
+ });
3250
+ this.input('scrollRange', ScrollRangeSelectInputView, {
3251
+ values: scrollRanges,
3252
+ translationKeys: pinnedScrollRangeKeys,
3253
+ ...illustrationOptions(contentElement),
3254
+ visibleBinding: ['playbackMode', 'position'],
3255
+ visible: ([playbackMode]) => playbackMode === 'scroll' && staysInPlace(contentElement)
3256
+ });
3257
+ this.view(SeparatorView);
3258
+ this.group('ContentElementPosition', {
3259
+ entry
3260
+ });
3261
+ this.view(SeparatorView);
3262
+ this.group('ContentElementCaption', {
3263
+ entry
3264
+ });
3265
+ this.group('ContentElementInlineFileRightsSettings');
3266
+ });
3267
+ }
3268
+ });
3269
+
3270
+ // Layouts that do not support sticky position render such elements
3271
+ // inline, which does not keep them in place while scrolling.
3272
+ function staysInPlace(contentElement) {
3273
+ return pinnedPositions.includes(contentElement.getResolvedPosition());
3274
+ }
3275
+
3276
+ // Illustrate options with the element as it looks in its section.
3277
+ function illustrationOptions(contentElement) {
3278
+ return {
3279
+ position: () => contentElement.getResolvedPosition(),
3280
+ sectionLayout: () => contentElement.section.configuration.get('layout')
3281
+ };
3282
+ }
3283
+
3284
+ var img$i = "data:image/svg+xml,%3csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e %3cpath fill='white' d='m 63.5%2c52 c -35%2c0 -63%2c29 -63%2c64 v 280 c 0%2c35 28%2c64 63%2c64 H 447 c 35%2c0 65%2c-29 65%2c-64 V 116 C 512%2c81 483%2c52 447%2c52 Z m 78.5%2c80 c 51%2c0 93%2c42 93%2c93 0%2c51 -42%2c93 -93%2c93 -51.4%2c0 -93%2c-42 -93%2c-93 0%2c-51 41.6%2c-93 93%2c-93 z m 172%2c15 h 113 c 19%2c0 34%2c15 34%2c34 0%2c19 -15%2c34 -34%2c34 H 314 c -19%2c0 -34%2c-15 -34%2c-34 0%2c-19 15%2c-34 34%2c-34 z m -13%2c111 h 116 c 11%2c0 21%2c10 21%2c21 0%2c12 -10%2c22 -21%2c22 H 301 c -11%2c0 -21%2c-10 -21%2c-22 0%2c-11 10%2c-21 21%2c-21 z'/%3e%3c/svg%3e";
3285
+
3286
+ function processBlueskyOembed(oembedResponse) {
3287
+ var parser = new DOMParser();
3288
+ var doc = parser.parseFromString(oembedResponse.html, 'text/html');
3289
+ var blockquote = doc.querySelector('blockquote.bluesky-embed');
3290
+ if (blockquote) {
3291
+ var dataUri = blockquote.getAttribute('data-bluesky-uri');
3292
+ if (dataUri) {
3293
+ return dataUri;
3294
+ }
3295
+ }
3296
+
3297
+ // Fallback to original URL if extraction fails
3298
+ return oembedResponse.url;
3299
+ }
3300
+
3301
+ editor.contentElementTypes.register('socialEmbed', {
3302
+ pictogram: img$i,
3303
+ category: 'media',
2671
3304
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2672
- configurationEditor: function configurationEditor(_ref) {
2673
- var entry = _ref.entry;
3305
+ featureName: 'social_embed_content_element',
3306
+ defaultConfig: {
3307
+ provider: 'bluesky'
3308
+ },
3309
+ configurationEditor({
3310
+ entry
3311
+ }) {
3312
+ this.tab('general', function () {
3313
+ this.input('provider', SelectInputView, {
3314
+ values: ['bluesky', 'instagram', 'tiktok', 'x']
3315
+ });
3316
+ this.input('url', OembedUrlInputView, {
3317
+ displayPropertyName: 'displayPostId',
3318
+ providerNameProperty: 'provider',
3319
+ providers: {
3320
+ bluesky: {
3321
+ supportedHosts: ['bsky.app', 'bsky.social'],
3322
+ transform: processBlueskyOembed
3323
+ },
3324
+ instagram: {
3325
+ supportedHosts: ['instagram.com', 'www.instagram.com'],
3326
+ skipOembedValidation: true
3327
+ },
3328
+ x: {
3329
+ supportedHosts: ['twitter.com', 'www.twitter.com', 'x.com', 'www.x.com'],
3330
+ skipOembedValidation: true
3331
+ },
3332
+ tiktok: {
3333
+ supportedHosts: ['https://www.tiktok.com'],
3334
+ skipOembedValidation: true
3335
+ }
3336
+ }
3337
+ });
3338
+ this.group('ContentElementPosition', {
3339
+ entry
3340
+ });
3341
+ this.input('hideConversation', CheckBoxInputView, {
3342
+ visibleBinding: 'provider',
3343
+ visibleBindingValue: 'x'
3344
+ });
3345
+ this.input('hideMedia', CheckBoxInputView, {
3346
+ visibleBinding: 'provider',
3347
+ visibleBindingValue: 'x'
3348
+ });
3349
+ });
3350
+ }
3351
+ });
3352
+
3353
+ var img$j = "data:image/svg+xml,%3csvg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e %3cpath fill='white' d='M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z'/%3e%3c/svg%3e";
3354
+
3355
+ editor.contentElementTypes.register('twitterEmbed', {
3356
+ pictogram: img$j,
3357
+ category: 'media',
3358
+ featureName: 'legacy_social_embed_content_elements',
3359
+ supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
3360
+ configurationEditor({
3361
+ entry
3362
+ }) {
2674
3363
  this.tab('general', function () {
2675
3364
  this.input('url', UrlInputView, {
2676
3365
  supportedHosts: ['http://twitter.com', 'https://twitter.com', 'http://x.com', 'https://x.com'],
@@ -2679,7 +3368,7 @@ editor.contentElementTypes.register('twitterEmbed', {
2679
3368
  permitHttps: true
2680
3369
  });
2681
3370
  this.group('ContentElementPosition', {
2682
- entry: entry
3371
+ entry
2683
3372
  });
2684
3373
  this.input('hideConversation', CheckBoxInputView);
2685
3374
  this.input('hideMedia', CheckBoxInputView);
@@ -2690,15 +3379,17 @@ editor.contentElementTypes.register('twitterEmbed', {
2690
3379
  }
2691
3380
  });
2692
3381
 
2693
- var img$i = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3e%3c!--!Font Awesome Free 6.5.2 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons%2c Inc.--%3e%3cpath fill='white' d='M448 209.9a210.1 210.1 0 0 1 -122.8-39.3V349.4A162.6 162.6 0 1 1 185 188.3V278.2a74.6 74.6 0 1 0 52.2 71.2V0l88 0a121.2 121.2 0 0 0 1.9 22.2h0A122.2 122.2 0 0 0 381 102.4a121.4 121.4 0 0 0 67 20.1z'/%3e%3c/svg%3e";
3382
+ var img$k = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3e%3c!--!Font Awesome Free 6.5.2 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons%2c Inc.--%3e%3cpath fill='white' d='M448 209.9a210.1 210.1 0 0 1 -122.8-39.3V349.4A162.6 162.6 0 1 1 185 188.3V278.2a74.6 74.6 0 1 0 52.2 71.2V0l88 0a121.2 121.2 0 0 0 1.9 22.2h0A122.2 122.2 0 0 0 381 102.4a121.4 121.4 0 0 0 67 20.1z'/%3e%3c/svg%3e";
2694
3383
 
2695
3384
  editor.contentElementTypes.register('tikTokEmbed', {
2696
- pictogram: img$i,
3385
+ pictogram: img$k,
2697
3386
  category: 'media',
3387
+ featureName: 'legacy_social_embed_content_elements',
2698
3388
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2699
3389
  supportedWidthRange: ['md', 'full'],
2700
- configurationEditor: function configurationEditor(_ref) {
2701
- var entry = _ref.entry;
3390
+ configurationEditor({
3391
+ entry
3392
+ }) {
2702
3393
  this.tab('general', function () {
2703
3394
  this.input('url', UrlInputView, {
2704
3395
  supportedHosts: ['https://www.tiktok.com'],
@@ -2707,54 +3398,53 @@ editor.contentElementTypes.register('tikTokEmbed', {
2707
3398
  permitHttps: true
2708
3399
  });
2709
3400
  this.group('ContentElementPosition', {
2710
- entry: entry
3401
+ entry
2711
3402
  });
2712
3403
  });
2713
3404
  },
2714
3405
  defaultConfig: {}
2715
3406
  });
2716
3407
 
2717
- var img$j = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3csvg xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' version='1.1'%3e %3cpath style='fill:white%3bstroke-width:1.0715934' d='M 154.45629%2c72.962988 C 141.76916%2c73.980674 134.17753%2c85.77696 126.39089%2c94.31369 115.08265%2c105.89861 104.03984%2c117.73757 92.93941%2c129.52047 75.031239%2c111.21828 59.122369%2c90.77981 39.104383%2c74.658023 24.482281%2c67.834512 6.4140221%2c83.81238 10.775786%2c99.1746 c 2.708951%2c12.98866 15.286417%2c19.97415 22.964661%2c29.74046 17.657732%2c17.41285 32.403074%2c38.12856 52.621136%2c52.73529 10.829773%2c3.83939 22.062597%2c-3.51996 28.134937%2c-12.18527 19.44195%2c-22.50249 42.21653%2c-42.18327 59.90279%2c-66.14032 5.6424%2c-13.25737 -5.31055%2c-30.615753 -19.94302%2c-30.361772 z' /%3e %3cpath style='fill:white' d='M 256%2c428 H 31.999999 C 14.329999%2c428 -9.5000001e-7%2c442.33 -9.5000001e-7%2c460 -9.5000001e-7%2c477.67 14.329999%2c492 31.999999%2c492 H 256 c 17.7%2c0 32%2c-14.33 32%2c-32 0%2c-17.67 -14.3%2c-32 -32%2c-32 z M -9.5000001e-7%2c332 C -9.5000001e-7%2c349.7 14.329999%2c364 31.999999%2c364 H 416 c 17.7%2c0 32%2c-14.3 32%2c-32 0%2c-17.7 -14.3%2c-32 -32%2c-32 H 31.999999 C 14.329999%2c300 -9.5000001e-7%2c314.3 -9.5000001e-7%2c332 Z' /%3e %3cpath style='fill:white%3bstroke:white%3bstroke-width:0' d='m 356.05605%2c1.671899 c -22.75276%2c2.300391 -47.49513%2c-4.661754 -68.50543%2c6.450454 -16.00534%2c8.484395 -29.74636%2c27.036262 -24.98608%2c45.803882 5.50667%2c15.699356 29.05588%2c21.427535 39.82967%2c7.900392 4.46727%2c-4.523763 5.45002%2c-13.464333 13.29935%2c-12.285569 15.47565%2c-0.207336 30.89377%2c0.32159 46.37678%2c-0.223975 7.3323%2c-0.346315 15.23462%2c5.874856 12.62272%2c13.740223 -2.68086%2c9.147994 -13.45058%2c10.823444 -20.24491%2c15.836144 -11.40111%2c6.6584 -24.83231%2c11.40873 -32.94777%2c22.30075 -5.41404%2c11.18313 -4.76974%2c25.17905 -0.0141%2c36.40876 8.15241%2c13.79679 31.57231%2c15.50575 40.17388%2c0.85347 4.19853%2c-4.46787 1.87713%2c-12.57946 8.75385%2c-14.22118 18.79687%2c-10.20424 40.72904%2c-20.78924 48.43263%2c-42.36648 C 431.32621%2c52.120851 413.71956%2c13.332394 382.01823%2c4.732093 373.62266%2c2.216616 364.78493%2c1.519639 356.05609%2c1.671899 Z M 341.22896%2c172.48634 c -21.90876%2c-0.63629 -38.00737%2c26.58485 -26.67177%2c45.4856 9.43025%2c18.07827 37.60246%2c22.17393 50.69123%2c5.8469 12.093%2c-13.5735 9.43272%2c-37.5803 -6.86539%2c-46.64791 -5.10378%2c-3.1728 -11.1363%2c-4.88155 -17.15407%2c-4.68459 z' /%3e%3c/svg%3e";
3408
+ var img$l = "data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e%3csvg xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' version='1.1'%3e %3cpath style='fill:white%3bstroke-width:1.0715934' d='M 154.45629%2c72.962988 C 141.76916%2c73.980674 134.17753%2c85.77696 126.39089%2c94.31369 115.08265%2c105.89861 104.03984%2c117.73757 92.93941%2c129.52047 75.031239%2c111.21828 59.122369%2c90.77981 39.104383%2c74.658023 24.482281%2c67.834512 6.4140221%2c83.81238 10.775786%2c99.1746 c 2.708951%2c12.98866 15.286417%2c19.97415 22.964661%2c29.74046 17.657732%2c17.41285 32.403074%2c38.12856 52.621136%2c52.73529 10.829773%2c3.83939 22.062597%2c-3.51996 28.134937%2c-12.18527 19.44195%2c-22.50249 42.21653%2c-42.18327 59.90279%2c-66.14032 5.6424%2c-13.25737 -5.31055%2c-30.615753 -19.94302%2c-30.361772 z' /%3e %3cpath style='fill:white' d='M 256%2c428 H 31.999999 C 14.329999%2c428 -9.5000001e-7%2c442.33 -9.5000001e-7%2c460 -9.5000001e-7%2c477.67 14.329999%2c492 31.999999%2c492 H 256 c 17.7%2c0 32%2c-14.33 32%2c-32 0%2c-17.67 -14.3%2c-32 -32%2c-32 z M -9.5000001e-7%2c332 C -9.5000001e-7%2c349.7 14.329999%2c364 31.999999%2c364 H 416 c 17.7%2c0 32%2c-14.3 32%2c-32 0%2c-17.7 -14.3%2c-32 -32%2c-32 H 31.999999 C 14.329999%2c300 -9.5000001e-7%2c314.3 -9.5000001e-7%2c332 Z' /%3e %3cpath style='fill:white%3bstroke:white%3bstroke-width:0' d='m 356.05605%2c1.671899 c -22.75276%2c2.300391 -47.49513%2c-4.661754 -68.50543%2c6.450454 -16.00534%2c8.484395 -29.74636%2c27.036262 -24.98608%2c45.803882 5.50667%2c15.699356 29.05588%2c21.427535 39.82967%2c7.900392 4.46727%2c-4.523763 5.45002%2c-13.464333 13.29935%2c-12.285569 15.47565%2c-0.207336 30.89377%2c0.32159 46.37678%2c-0.223975 7.3323%2c-0.346315 15.23462%2c5.874856 12.62272%2c13.740223 -2.68086%2c9.147994 -13.45058%2c10.823444 -20.24491%2c15.836144 -11.40111%2c6.6584 -24.83231%2c11.40873 -32.94777%2c22.30075 -5.41404%2c11.18313 -4.76974%2c25.17905 -0.0141%2c36.40876 8.15241%2c13.79679 31.57231%2c15.50575 40.17388%2c0.85347 4.19853%2c-4.46787 1.87713%2c-12.57946 8.75385%2c-14.22118 18.79687%2c-10.20424 40.72904%2c-20.78924 48.43263%2c-42.36648 C 431.32621%2c52.120851 413.71956%2c13.332394 382.01823%2c4.732093 373.62266%2c2.216616 364.78493%2c1.519639 356.05609%2c1.671899 Z M 341.22896%2c172.48634 c -21.90876%2c-0.63629 -38.00737%2c26.58485 -26.67177%2c45.4856 9.43025%2c18.07827 37.60246%2c22.17393 50.69123%2c5.8469 12.093%2c-13.5735 9.43272%2c-37.5803 -6.86539%2c-46.64791 -5.10378%2c-3.1728 -11.1363%2c-4.88155 -17.15407%2c-4.68459 z' /%3e%3c/svg%3e";
2718
3409
 
2719
3410
  editor.contentElementTypes.register('question', {
2720
- pictogram: img$j,
3411
+ pictogram: img$l,
2721
3412
  supportedPositions: ['inline'],
2722
- configurationEditor: function configurationEditor(_ref) {
2723
- var entry = _ref.entry,
2724
- contentElement = _ref.contentElement;
3413
+ configurationEditor({
3414
+ entry,
3415
+ contentElement
3416
+ }) {
2725
3417
  this.tab('general', function () {
2726
- var modelDelegator = entry.createLegacyTypographyVariantDelegator({
3418
+ const modelDelegator = entry.createLegacyTypographyVariantDelegator({
2727
3419
  model: this.model,
2728
3420
  paletteColorPropertyName: 'color'
2729
3421
  });
2730
3422
  this.group('ContentElementTypographyVariant', {
2731
- entry: entry,
3423
+ entry,
2732
3424
  model: modelDelegator,
2733
- getPreviewConfiguration: function getPreviewConfiguration(configuration, typographyVariant) {
2734
- return _objectSpread2(_objectSpread2({}, configuration), {}, {
2735
- expandByDefault: true,
2736
- typographyVariant: typographyVariant
2737
- });
2738
- }
3425
+ getPreviewConfiguration: (configuration, typographyVariant) => ({
3426
+ ...configuration,
3427
+ expandByDefault: true,
3428
+ typographyVariant
3429
+ })
2739
3430
  });
2740
3431
  this.group('ContentElementTypographySize', {
2741
- entry: entry,
3432
+ entry,
2742
3433
  model: modelDelegator,
2743
- getPreviewConfiguration: function getPreviewConfiguration(configuration, typographySize) {
2744
- return _objectSpread2(_objectSpread2({}, configuration), {}, {
2745
- expandByDefault: true,
2746
- // Ensure size in preview is not overridden by legacy variant
2747
- typographyVariant: modelDelegator.get('typographyVariant'),
2748
- typographySize: typographySize
2749
- });
2750
- }
3434
+ getPreviewConfiguration: (configuration, typographySize) => ({
3435
+ ...configuration,
3436
+ expandByDefault: true,
3437
+ // Ensure size in preview is not overridden by legacy variant
3438
+ typographyVariant: modelDelegator.get('typographyVariant'),
3439
+ typographySize
3440
+ })
2751
3441
  });
2752
3442
  this.group('PaletteColor', {
2753
- entry: entry,
3443
+ entry,
2754
3444
  propertyName: 'color'
2755
3445
  });
2756
3446
  this.group('PaletteColor', {
2757
- entry: entry,
3447
+ entry,
2758
3448
  propertyName: 'answerColor'
2759
3449
  });
2760
3450
  this.input('expandByDefault', CheckBoxInputView);
@@ -2762,32 +3452,53 @@ editor.contentElementTypes.register('question', {
2762
3452
  }
2763
3453
  });
2764
3454
 
2765
- var img$k = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3e%3cpath fill='white' d='M181.3 32.4c17.4 2.9 29.2 19.4 26.3 36.8L197.8 128h95.1l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3s29.2 19.4 26.3 36.8L357.8 128H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H347.1L325.8 320H384c17.7 0 32 14.3 32 32s-14.3 32-32 32H315.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8l9.8-58.7H155.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8L90.2 384H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l21.3-128H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3zM187.1 192L165.8 320h95.1l21.3-128H187.1z'/%3e%3c/svg%3e";
3455
+ const legacyTextSizes = {
3456
+ verySmall: 'xs',
3457
+ small: 'md',
3458
+ medium: 'xl',
3459
+ large: 'xxxl'
3460
+ };
3461
+ function createLegacyConfigurationDelegator(model) {
3462
+ const delegator = Object.create(model);
3463
+ delegator.get = function (name) {
3464
+ const result = model.get(name);
3465
+ if (name === 'numberSize') {
3466
+ return result || legacyTextSizes[model.get('textSize')];
3467
+ }
3468
+ if (name === 'countingAnimation') {
3469
+ const countingSpeed = model.get('countingSpeed');
3470
+ return result || (countingSpeed && countingSpeed !== 'none' ? 'plain' : undefined);
3471
+ }
3472
+ return result;
3473
+ };
3474
+ return delegator;
3475
+ }
3476
+
3477
+ var img$m = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3e%3cpath fill='white' d='M181.3 32.4c17.4 2.9 29.2 19.4 26.3 36.8L197.8 128h95.1l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3s29.2 19.4 26.3 36.8L357.8 128H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H347.1L325.8 320H384c17.7 0 32 14.3 32 32s-14.3 32-32 32H315.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8l9.8-58.7H155.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8L90.2 384H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l21.3-128H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3zM187.1 192L165.8 320h95.1l21.3-128H187.1z'/%3e%3c/svg%3e";
2766
3478
 
2767
3479
  editor.contentElementTypes.register('counter', {
2768
3480
  category: 'data',
2769
- pictogram: img$k,
3481
+ pictogram: img$m,
2770
3482
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2771
3483
  supportedWidthRange: ['xxs', 'full'],
2772
3484
  defaultConfig: {
2773
3485
  targetValue: 100,
2774
- countingSpeed: 'medium',
2775
- textSize: 'medium'
3486
+ countingSpeed: 'medium'
2776
3487
  },
2777
- configurationEditor: function configurationEditor(_ref) {
2778
- var entry = _ref.entry;
2779
- var locale = entry.metadata.get('locale');
3488
+ configurationEditor({
3489
+ entry
3490
+ }) {
3491
+ const locale = entry.metadata.get('locale');
2780
3492
  this.tab('general', function () {
3493
+ const modelDelegator = createLegacyConfigurationDelegator(this.model);
2781
3494
  this.input('targetValue', NumberInputView, {
2782
- locale: locale
3495
+ locale
2783
3496
  });
2784
3497
  this.input('decimalPlaces', SelectInputView, {
2785
3498
  values: [0, 1, 2, 3],
2786
- texts: [0, 1, 2, 3].map(function (i) {
2787
- return 0 .toLocaleString(locale, {
2788
- minimumFractionDigits: i
2789
- });
2790
- })
3499
+ texts: [0, 1, 2, 3].map(i => 0 .toLocaleString(locale, {
3500
+ minimumFractionDigits: i
3501
+ }))
2791
3502
  });
2792
3503
  this.input('thousandsSeparators', CheckBoxInputView, {
2793
3504
  storeInverted: 'hideThousandsSeparators'
@@ -2797,70 +3508,131 @@ editor.contentElementTypes.register('counter', {
2797
3508
  values: ['trailing', 'leading']
2798
3509
  });
2799
3510
  this.view(SeparatorView);
3511
+ const [numberSizes, numberTexts] = entry.getTypographySizes({
3512
+ scaleCategory: 'counterNumber',
3513
+ texts: 'short',
3514
+ order: 'asc'
3515
+ });
3516
+ this.input('numberSize', SliderInputView, {
3517
+ model: modelDelegator,
3518
+ values: numberSizes,
3519
+ texts: numberTexts,
3520
+ defaultValue: 'xl',
3521
+ saveOnSlide: true
3522
+ });
3523
+ const [unitSizes, unitTexts] = entry.getTypographySizes({
3524
+ scaleCategory: 'counterUnit',
3525
+ texts: 'short',
3526
+ order: 'asc'
3527
+ });
3528
+ this.input('unitSize', SliderInputView, {
3529
+ values: unitSizes,
3530
+ texts: unitTexts,
3531
+ defaultValue: 'md',
3532
+ saveOnSlide: true,
3533
+ visibleBinding: 'unit',
3534
+ visible: unit => !!unit
3535
+ });
3536
+ const [descriptionSizes, descriptionTexts] = entry.getTypographySizes({
3537
+ scaleCategory: 'counterDescription',
3538
+ texts: 'short',
3539
+ order: 'asc'
3540
+ });
3541
+ this.input('descriptionSize', SliderInputView, {
3542
+ values: descriptionSizes,
3543
+ texts: descriptionTexts,
3544
+ defaultValue: 'md',
3545
+ saveOnSlide: true
3546
+ });
3547
+ this.view(SeparatorView);
3548
+ this.group('PaletteColor', {
3549
+ propertyName: 'numberColor',
3550
+ entry
3551
+ });
3552
+ this.group('PaletteColor', {
3553
+ propertyName: 'unitColor',
3554
+ entry,
3555
+ visibleBinding: 'unit',
3556
+ visible: unit => !!unit
3557
+ });
3558
+ this.group('PaletteColor', {
3559
+ propertyName: 'descriptionColor',
3560
+ entry
3561
+ });
3562
+ this.view(SeparatorView);
2800
3563
  this.input('entranceAnimation', SelectInputView, {
2801
3564
  values: ['none', 'fadeIn', 'fadeInFromBelow', 'fadeInFromAbove', 'fadeInScaleUp', 'fadeInScaleDown']
2802
3565
  });
3566
+ this.input('countingAnimation', SelectInputView, {
3567
+ model: modelDelegator,
3568
+ values: ['none', 'plain', 'wheel']
3569
+ });
2803
3570
  this.input('countingSpeed', SelectInputView, {
2804
- values: ['none', 'slow', 'medium', 'fast']
3571
+ model: modelDelegator,
3572
+ values: ['slow', 'medium', 'fast'],
3573
+ visibleBinding: 'countingAnimation',
3574
+ visible: countingAnimation => countingAnimation && countingAnimation !== 'none'
2805
3575
  });
2806
3576
  this.input('startValue', NumberInputView, {
2807
- locale: locale,
2808
- visibleBinding: 'countingSpeed',
2809
- visible: function visible(countingSpeed) {
2810
- return countingSpeed !== 'none';
2811
- }
3577
+ model: modelDelegator,
3578
+ locale,
3579
+ visibleBinding: 'countingAnimation',
3580
+ visible: countingAnimation => countingAnimation && countingAnimation !== 'none'
2812
3581
  });
2813
- this.view(SeparatorView);
2814
- this.input('textSize', SelectInputView, {
2815
- values: ['large', 'medium', 'small', 'verySmall']
3582
+ this.input('startAnimationTrigger', SelectInputView, {
3583
+ model: modelDelegator,
3584
+ values: ['onActivate', 'onVisible'],
3585
+ visibleBinding: ['entranceAnimation', 'countingAnimation'],
3586
+ visible: ([entranceAnimation, countingAnimation]) => (entranceAnimation || 'none') !== 'none' || countingAnimation && countingAnimation !== 'none'
2816
3587
  });
3588
+ this.view(SeparatorView);
2817
3589
  this.group('ContentElementTypographyVariant', {
2818
- entry: entry,
2819
- getPreviewConfiguration: function getPreviewConfiguration(configuration, typographyVariant) {
2820
- return _objectSpread2(_objectSpread2({}, configuration), {}, {
2821
- typographyVariant: typographyVariant,
2822
- entranceAnimation: 'none',
2823
- countingSpeed: 'none',
2824
- textSize: 'small',
2825
- position: 'inline'
2826
- });
2827
- }
3590
+ entry,
3591
+ getPreviewConfiguration: (configuration, typographyVariant) => ({
3592
+ ...configuration,
3593
+ typographyVariant,
3594
+ entranceAnimation: 'none',
3595
+ countingSpeed: 'none',
3596
+ numberSize: 'sm',
3597
+ position: 'inline'
3598
+ })
2828
3599
  });
2829
- this.group('PaletteColor', {
2830
- propertyName: 'numberColor',
2831
- entry: entry
3600
+ this.input('textAlign', SelectInputView, {
3601
+ values: ['left', 'right', 'center', 'centerRagged'],
3602
+ includeBlank: true
2832
3603
  });
2833
3604
  this.group('ContentElementPosition', {
2834
- entry: entry
3605
+ entry
2835
3606
  });
2836
3607
  });
2837
3608
  }
2838
3609
  });
2839
3610
 
2840
- var img$l = "data:image/svg+xml,%3csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='quote-right' class='svg-inline--fa fa-quote-right fa-w-16' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-50 -50 612 612'%3e%3cpath fill='white' d='M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z'%3e%3c/path%3e%3c/svg%3e";
3611
+ var img$n = "data:image/svg+xml,%3csvg aria-hidden='true' focusable='false' data-prefix='fas' data-icon='quote-right' class='svg-inline--fa fa-quote-right fa-w-16' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='-50 -50 612 612'%3e%3cpath fill='white' d='M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z'%3e%3c/path%3e%3c/svg%3e";
2841
3612
 
2842
3613
  editor.contentElementTypes.register('quote', {
2843
- pictogram: img$l,
3614
+ pictogram: img$n,
2844
3615
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2845
3616
  supportedWidthRange: ['xs', 'xl'],
2846
3617
  defaultConfig: {
2847
3618
  textSize: 'medium'
2848
3619
  },
2849
- configurationEditor: function configurationEditor(_ref) {
2850
- var entry = _ref.entry;
3620
+ configurationEditor({
3621
+ entry
3622
+ }) {
2851
3623
  this.tab('general', function () {
2852
3624
  this.group('ContentElementVariant', {
2853
- entry: entry
3625
+ entry
2854
3626
  });
2855
3627
  this.input('textSize', SelectInputView, {
2856
3628
  values: ['large', 'medium', 'small', 'verySmall']
2857
3629
  });
2858
3630
  this.group('ContentElementPosition', {
2859
- entry: entry
3631
+ entry
2860
3632
  });
2861
3633
  this.group('PaletteColor', {
2862
3634
  propertyName: 'color',
2863
- entry: entry
3635
+ entry
2864
3636
  });
2865
3637
  this.view(SeparatorView);
2866
3638
  this.view(InfoBoxView, {
@@ -2870,15 +3642,16 @@ editor.contentElementTypes.register('quote', {
2870
3642
  }
2871
3643
  });
2872
3644
 
2873
- var img$m = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3c!--!Font Awesome Free 6.7.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons%2c Inc.--%3e%3cpath fill='white' d='M 446%2c37.9 C 341%2c38.2 236%2c37.8 132%2c38 106%2c38.4 80.7%2c37.3 55.3%2c38.5 26.6%2c42.6 3.13%2c70.8 6.21%2c100 5.84%2c203 5.94%2c305 6.15%2c408 c -0.18%2c12 0.3%2c26 7.25%2c36 11.2%2c20 34.2%2c33 57%2c30 128.6%2c0 256.6%2c0 384.6%2c0 30%2c-4 55%2c-34 51%2c-64 0%2c-107 0%2c-215 0%2c-322.2 C 501%2c59.7 475%2c36.7 446%2c37.9 Z M 60%2c90 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z M 60%2c218 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z M 60%2c346 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z' /%3e%3c/svg%3e";
3645
+ var img$o = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3c!--!Font Awesome Free 6.7.1 by %40fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons%2c Inc.--%3e%3cpath fill='white' d='M 446%2c37.9 C 341%2c38.2 236%2c37.8 132%2c38 106%2c38.4 80.7%2c37.3 55.3%2c38.5 26.6%2c42.6 3.13%2c70.8 6.21%2c100 5.84%2c203 5.94%2c305 6.15%2c408 c -0.18%2c12 0.3%2c26 7.25%2c36 11.2%2c20 34.2%2c33 57%2c30 128.6%2c0 256.6%2c0 384.6%2c0 30%2c-4 55%2c-34 51%2c-64 0%2c-107 0%2c-215 0%2c-322.2 C 501%2c59.7 475%2c36.7 446%2c37.9 Z M 60%2c90 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z M 60%2c218 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z M 60%2c346 c 24.7%2c0 49%2c0 74%2c0 0%2c25 0%2c51 0%2c76 -25%2c0 -50.7%2c0 -76%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z m 128%2c0 c 89%2c0 177%2c0 266%2c0 0%2c25 0%2c51 0%2c76 -89%2c0 -179%2c0 -268%2c0 0%2c-25 0%2c-51 0%2c-76 h 1 z' /%3e%3c/svg%3e";
2874
3646
 
2875
3647
  editor.contentElementTypes.register('infoTable', {
2876
- pictogram: img$m,
3648
+ pictogram: img$o,
2877
3649
  supportedPositions: ['inline', 'side', 'sticky', 'standAlone', 'left', 'right'],
2878
3650
  supportedWidthRange: ['s', 'xl'],
2879
- configurationEditor: function configurationEditor(_ref) {
2880
- var entry = _ref.entry,
2881
- contentElement = _ref.contentElement;
3651
+ configurationEditor({
3652
+ entry,
3653
+ contentElement
3654
+ }) {
2882
3655
  this.tab('general', function () {
2883
3656
  this.input('labelColumnAlign', SelectInputView, {
2884
3657
  values: ['auto', 'left', 'center', 'right']
@@ -2894,15 +3667,15 @@ editor.contentElementTypes.register('infoTable', {
2894
3667
  this.view(SeparatorView);
2895
3668
  this.group('PaletteColor', {
2896
3669
  propertyName: 'labelColor',
2897
- entry: entry
3670
+ entry
2898
3671
  });
2899
3672
  this.group('PaletteColor', {
2900
3673
  propertyName: 'valueColor',
2901
- entry: entry
3674
+ entry
2902
3675
  });
2903
3676
  this.view(SeparatorView);
2904
3677
  this.group('ContentElementPosition', {
2905
- entry: entry
3678
+ entry
2906
3679
  });
2907
3680
  this.view(SeparatorView);
2908
3681
  this.view(InfoBoxView, {
@@ -2911,3 +3684,48 @@ editor.contentElementTypes.register('infoTable', {
2911
3684
  });
2912
3685
  }
2913
3686
  });
3687
+
3688
+ // Headings carry no ranged comments since EditableInlineText has no
3689
+ // commenting alternative, so every comment refers to the header as a whole
3690
+ // and the quote covers all three of its texts.
3691
+ review.contentElementTypes.register('heading', {
3692
+ extractQuote(configuration) {
3693
+ const parts = [inlineText(configuration.tagline), mainText(configuration), inlineText(configuration.subtitle)];
3694
+ return parts.map(part => part.trim()).filter(Boolean).join('\n') || null;
3695
+ }
3696
+ });
3697
+
3698
+ // Mirrors how EditableInlineText picks the legacy string value, so the quote
3699
+ // never contains text the heading does not display.
3700
+ function mainText(configuration) {
3701
+ return configuration.value ? inlineText(configuration.value) : configuration.children || '';
3702
+ }
3703
+ function inlineText(value) {
3704
+ return value ? value.map(node => Node.string(node)).join(' ') : '';
3705
+ }
3706
+
3707
+ review.contentElementTypes.register('textBlock', {
3708
+ compareRanges(a, b) {
3709
+ if (!a && !b) return 0;
3710
+ if (!a) return 1;
3711
+ if (!b) return -1;
3712
+ return Point.compare(rangeStart(a), rangeStart(b));
3713
+ },
3714
+ // Element wide comments stay unquoted: the whole text is too long to serve
3715
+ // as a point of reference, and any edit anywhere in it would mark the quote
3716
+ // outdated.
3717
+ extractQuote(configuration, range) {
3718
+ if (!range) return null;
3719
+ const root = {
3720
+ children: configuration.value || []
3721
+ };
3722
+ if (!Node.has(root, range.anchor.path) || !Node.has(root, range.focus.path)) {
3723
+ return null;
3724
+ }
3725
+ const text = Node.fragment(root, range).map(node => Node.string(node)).join('\n').trim();
3726
+ return text || null;
3727
+ }
3728
+ });
3729
+ function rangeStart(range) {
3730
+ return Point.isBefore(range.anchor, range.focus) ? range.anchor : range.focus;
3731
+ }